From f728abb3c350b8b5f8e74aaea5aa27007237f45c Mon Sep 17 00:00:00 2001 From: Cristian Date: Sun, 2 May 2021 12:54:01 -0500 Subject: [PATCH 01/10] feat: Enable passing explicit urls to exclude from instrumentation in fastapi --- .../README.rst | 5 +++ .../instrumentation/fastapi/__init__.py | 23 +++++++--- .../tests/test_fastapi_instrumentation.py | 42 ++++++++++++++++++- 3 files changed, 64 insertions(+), 6 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/README.rst b/instrumentation/opentelemetry-instrumentation-fastapi/README.rst index ab76664448..3f174e34d0 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/README.rst +++ b/instrumentation/opentelemetry-instrumentation-fastapi/README.rst @@ -51,6 +51,11 @@ Usage FastAPIInstrumentor.instrument_app(app) +You can also pass the list of urls to exclude explicitly to the instrumentation call: + +.. code-block:: python + from opentelemetry.util.http import ExcludeList + FastAPIInstrumentor.instrument_app(app, ExcludeList("client/.*/info,healthcheck")) References ---------- 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 9f3abf6d88..b14ffbff98 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py @@ -32,13 +32,19 @@ class FastAPIInstrumentor(BaseInstrumentor): _original_fastapi = None @staticmethod - def instrument_app(app: fastapi.FastAPI, tracer_provider=None): - """Instrument an uninstrumented FastAPI application. - """ + def instrument_app( + app: fastapi.FastAPI, + tracer_provider=None, + excluded_urls=None, + ): + """Instrument an uninstrumented FastAPI application.""" if not getattr(app, "is_instrumented_by_opentelemetry", False): + if excluded_urls is None: + excluded_urls = _excluded_urls + app.add_middleware( OpenTelemetryMiddleware, - excluded_urls=_excluded_urls, + excluded_urls=excluded_urls, span_details_callback=_get_route_details, tracer_provider=tracer_provider, ) @@ -47,6 +53,7 @@ def instrument_app(app: fastapi.FastAPI, tracer_provider=None): def _instrument(self, **kwargs): self._original_fastapi = fastapi.FastAPI _InstrumentedFastAPI._tracer_provider = kwargs.get("tracer_provider") + _InstrumentedFastAPI._excluded_urls = kwargs.get("excluded_urls") fastapi.FastAPI = _InstrumentedFastAPI def _uninstrument(self, **kwargs): @@ -55,12 +62,18 @@ def _uninstrument(self, **kwargs): class _InstrumentedFastAPI(fastapi.FastAPI): _tracer_provider = None + _excluded_urls = None def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + excluded_urls = ( + _InstrumentedFastAPI._excluded_urls + if _InstrumentedFastAPI._excluded_urls is not None + else _excluded_urls + ) self.add_middleware( OpenTelemetryMiddleware, - excluded_urls=_excluded_urls, + excluded_urls=excluded_urls, span_details_callback=_get_route_details, tracer_provider=_InstrumentedFastAPI._tracer_provider, ) diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py index 524d53c6f9..1f4c699420 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py @@ -22,7 +22,7 @@ from opentelemetry.sdk.resources import Resource from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.test.test_base import TestBase -from opentelemetry.util.http import get_excluded_urls +from opentelemetry.util.http import get_excluded_urls, ExcludeList class TestFastAPIManualInstrumentation(TestBase): @@ -31,6 +31,17 @@ def _create_app(self): self._instrumentor.instrument_app(app) return app + def _create_app_explicit_excluded_urls(self): + app = self._create_fastapi_app() + to_exclude = "/user/123,/foobar" + excluded_urls = [ + excluded_url.strip() for excluded_url in to_exclude.split(",") + ] + self._instrumentor.instrument_app( + app, excluded_urls=ExcludeList(excluded_urls) + ) + return app + def setUp(self): super().setUp() self.env_patch = patch.dict( @@ -84,6 +95,17 @@ def test_fastapi_excluded_urls(self): spans = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans), 0) + def test_fastapi_excluded_urls_not_env(self): + """Ensure that given fastapi routes are excluded when passed explicitly (not in the environment)""" + app = self._create_app_explicit_excluded_urls() + client = TestClient(app) + client.get("/user/123") + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 0) + client.get("/foobar") + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 0) + @staticmethod def _create_fastapi_app(): app = fastapi.FastAPI() @@ -124,6 +146,24 @@ def _create_app(self): self._instrumentor.instrument(tracer_provider=tracer_provider) return self._create_fastapi_app() + def _create_app_explicit_excluded_urls(self): + resource = Resource.create({"key1": "value1", "key2": "value2"}) + tracer_provider, exporter = self.create_tracer_provider( + resource=resource + ) + self.memory_exporter = exporter + + to_exclude = "/user/123,/foobar" + excluded_urls = [ + excluded_url.strip() for excluded_url in to_exclude.split(",") + ] + self._instrumentor.uninstrument() # Disable previous instrumentation (setUp) + self._instrumentor.instrument( + tracer_provider=tracer_provider, + excluded_urls=ExcludeList(excluded_urls), + ) + return self._create_fastapi_app() + def test_request(self): self._client.get("/foobar") spans = self.memory_exporter.get_finished_spans() From 8c4eee0685c3de57d347dd1a29d2bf5999b3d368 Mon Sep 17 00:00:00 2001 From: Cristian Date: Sun, 2 May 2021 13:06:15 -0500 Subject: [PATCH 02/10] docs: Update changelog (fastapi #486) --- CHANGELOG.md | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d042f845b..16b67babed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ # Changelog + All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), @@ -12,14 +13,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#472](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/472)) - Set the `traced_request_attrs` of FalconInstrumentor by an argument correctly. ([#473](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/473)) +- Enable passing explicit urls to exclude in instrumentation in FastAPI + ([#486](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/486)) ### Added + - Move `opentelemetry-instrumentation` from core repository ([#465](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/465)) ## [0.20b0](https://github.com/open-telemetry/opentelemetry-python-contrib/releases/tag/v0.20b0) - 2021-04-20 ### Changed + - Restrict DataDog exporter's `ddtrace` dependency to known working versions. ([#400](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/400)) - GRPC instrumentation now correctly injects trace context into outgoing requests. @@ -31,7 +36,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Update instrumentations to use tracer_provider for creating tracer if given, otherwise use global tracer provider ([#402](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/402)) - `opentelemetry-instrumentation-wsgi` Replaced `name_callback` with `request_hook` - and `response_hook` callbacks. + and `response_hook` callbacks. ([#424](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/424)) - Update gRPC instrumentation to better wrap server context ([#420](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/420)) @@ -41,6 +46,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#265](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/265)) ### Added + - `opentelemetry-instrumentation-urllib3` Add urllib3 instrumentation ([#299](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/299)) - `opentelemetry-instrumenation-django` now supports request and response hooks. @@ -63,16 +69,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#436](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/436)) ### Removed + - Remove `http.status_text` from span attributes ([#406](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/406)) - ## [0.19b0](https://github.com/open-telemetry/opentelemetry-python-contrib/releases/tag/v0.19b0) - 2021-03-26 - Implement context methods for `_InterceptorChannel` ([#363](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/363)) ### Changed + - Rename `IdsGenerator` to `IdGenerator` ([#350](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/350)) - `opentelemetry-exporter-datadog` Fix warning when DatadogFormat encounters a request with @@ -92,18 +99,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#372](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/372)) ### Removed + - Removing support for Python 3.5 ([#374](https://github.com/open-telemetry/opentelemetry-python/pull/374)) ## [0.18b0](https://github.com/open-telemetry/opentelemetry-python-contrib/releases/tag/v0.18b0) - 2021-02-16 ### Added + - `opentelemetry-propagator-ot-trace` Add OT Trace Propagator ([#302](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/302)) - `opentelemetry-instrumentation-logging` Added logging instrumentation to enable log - trace correlation. ([#345](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/345)) ### Removed + - Remove `component` span attribute in instrumentations. `opentelemetry-instrumentation-aiopg`, `opentelemetry-instrumentation-dbapi` Remove unused `database_type` parameter from `trace_integration` function. ([#301](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/301)) @@ -121,6 +131,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.17b0](https://github.com/open-telemetry/opentelemetry-python-contrib/releases/tag/v0.17b0) - 2021-01-20 ### Added + - `opentelemetry-instrumentation-sqlalchemy` Ensure spans have kind set to "CLIENT" ([#278](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/278)) - `opentelemetry-instrumentation-celery` Add support for Celery version 5.x @@ -155,6 +166,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#273](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/273)) ### Changed + - Fix broken links to project ([#413](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/413)) - `opentelemetry-instrumentation-asgi`, `opentelemetry-instrumentation-wsgi` Return `None` for `CarrierGetter` if key not found ([#233](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/233)) @@ -184,6 +196,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#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)) @@ -192,6 +205,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.16b0](https://github.com/open-telemetry/opentelemetry-python-contrib/releases/tag/v0.16b0) - 2020-11-25 ### Added + - `opentelemetry-instrumentation-flask` Add span name callback ([#152](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/152)) - `opentelemetry-sdk-extension-aws` Add AWS X-Ray Ids Generator Entry Point @@ -210,6 +224,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#181](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/181)) ### Changed + - `opentelemetry-instrumentation-pymemcache` Update pymemcache instrumentation to follow semantic conventions ([#183](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/183)) - `opentelemetry-instrumentation-redis` Update redis instrumentation to follow semantic conventions @@ -234,6 +249,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.15b0](https://github.com/open-telemetry/opentelemetry-python-contrib/releases/tag/v0.15b0) - 2020-11-02 ### Added + - `opentelemetry-instrumentation-requests` Add support for tracking http metrics ([#1230](https://github.com/open-telemetry/opentelemetry-python/pull/1230)) - `opentelemetry-instrumentation-django` Added capture of http.route @@ -242,6 +258,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#1230](https://github.com/open-telemetry/opentelemetry-python/pull/1230)) ### Changed + - `opentelemetry-exporter-datadog` Make `SpanProcessor.on_start` accept parent Context ([#1251](https://github.com/open-telemetry/opentelemetry-python/pull/1251)) - `opentelemetry-instrumentation-flask` Use `url.rule` instead of `request.endpoint` for span name @@ -258,6 +275,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.14b0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v0.14b0) - 2020-10-13 ### Added + - `opentelemetry-exporter-datadog` Add support for span resource labels and service name - `opentelemetry-instrumentation-celery` Span operation names now include the task type. ([#1135](https://github.com/open-telemetry/opentelemetry-python/pull/1135)) @@ -271,6 +289,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#1154](https://github.com/open-telemetry/opentelemetry-python/pull/1154)) ### Changed + - `opentelemetry-instrumentation-pymongo` Cast PyMongo commands as strings ([#1132](https://github.com/open-telemetry/opentelemetry-python/pull/1132)) - `opentelemetry-instrumentation-system-metrics` Fix issue when specific metrics are not available in certain OS @@ -283,6 +302,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.13b0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v0.13b0) - 2020-09-17 ### Added + - `opentelemetry-instrumentation-falcon` Initial release. Added instrumentation for Falcon 2.0+ - `opentelemetry-instrumentation-tornado` Initial release. Supports Tornado 6.x on Python 3.5 and newer. - `opentelemetry-instrumentation-aiohttp-client` Add instrumentor and auto instrumentation support for aiohttp @@ -293,18 +313,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#1116](https://github.com/open-telemetry/opentelemetry-python/pull/1116)) ### Changed + - `opentelemetry-instrumentation-aiohttp-client` Updating span name to match semantic conventions ([#972](https://github.com/open-telemetry/opentelemetry-python/pull/972)) - `opentelemetry-instrumentation-dbapi` cursors and connections now produce spans when used with context managers ([#1028](https://github.com/open-telemetry/opentelemetry-python/pull/1028)) ### Removed + - Drop support for Python 3.4 ([#1099](https://github.com/open-telemetry/opentelemetry-python/pull/1099)) ## [0.12b0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v0.12.0) - 2020-08-14 ### Changed + - `opentelemetry-ext-pymemcache` Change package name to opentelemetry-instrumentation-pymemcache ([#966](https://github.com/open-telemetry/opentelemetry-python/pull/966)) - `opentelemetry-ext-redis` Update default SpanKind to `SpanKind.CLIENT` @@ -371,6 +394,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.11b0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v0.11.0) - 2020-07-28 ### Added + - `opentelemetry-instrumentation-aiopg` Initial release - `opentelemetry-instrumentation-fastapi` Initial release ([#890](https://github.com/open-telemetry/opentelemetry-python/pull/890)) @@ -381,6 +405,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-ext-grpc` Add metric recording (bytes in/out, errors, latency) to gRPC client ### Changed + - `opentelemetry-ext-pyramid` Use one general exclude list instead of two ([#872](https://github.com/open-telemetry/opentelemetry-python/pull/872)) - `opentelemetry-ext-boto` fails to export spans via jaeger @@ -401,6 +426,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.10b0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v0.10.0) - 2020-06-23 ### Added + - `opentelemetry-ext-pymemcache` Initial release - `opentelemetry-ext-elasticsearch` Initial release - `opentelemetry-ext-celery` Add instrumentation for Celery @@ -413,6 +439,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.9b0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v0.9.0) - 2020-06-10 ### Added + - `opentelemetry-ext-pyramid` Initial release - `opentelemetry-ext-boto` Initial release - `opentelemetry-ext-botocore` Initial release @@ -422,6 +449,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.8b0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v0.8.0) - 2020-05-27 ### Added + - `opentelemetry-ext-datadog` Add exporter to Datadog ([#572](https://github.com/open-telemetry/opentelemetry-python/pull/572)) - `opentelemetry-ext-sqlite3` Initial release @@ -434,12 +462,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-ext-django` Add support for django >= 1.10 (#717) ### Changed + - `opentelemetry-ext-grpc` lint: version of grpc causes lint issues ([#696](https://github.com/open-telemetry/opentelemetry-python/pull/696)) ## [0.7b1](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v0.7.1) - 2020-05-12 ### Added + - `opentelemetry-ext-redis` Initial release - `opentelemetry-ext-jinja2` Add jinja2 instrumentation ([#643](https://github.com/open-telemetry/opentelemetry-python/pull/643)) @@ -463,12 +493,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#654](https://github.com/open-telemetry/opentelemetry-python/pull/654)) ### Changed + - `opentelemetry-ext-http-requests` Rename package to opentelemetry-ext-requests ([#619](https://github.com/open-telemetry/opentelemetry-python/pull/619)) ## [0.6b0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v0.6.0) - 2020-03-30 ### Added + - `opentelemetry-ext-flask` Add an entry_point to be usable in auto-instrumentation ([#327](https://github.com/open-telemetry/opentelemetry-python/pull/327)) - `opentelemetry-ext-grpc` Add gRPC integration @@ -479,11 +511,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.4a0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v0.4.0) - 2020-02-21 ### Added + - `opentelemetry-ext-psycopg2` Initial release - `opentelemetry-ext-dbapi` Initial release - `opentelemetry-ext-mysql` Initial release ### Changed + - `opentelemetry-ext-pymongo` Updating network connection attribute names ([#350](https://github.com/open-telemetry/opentelemetry-python/pull/350)) - `opentelemetry-ext-wsgi` Updating network connection attribute names @@ -494,10 +528,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.3a0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v0.3.0) - 2019-12-11 ### Added + - `opentelemetry-ext-flask` Initial release - `opentelemetry-ext-pymongo` Initial release ### Changed + - `opentelemetry-ext-wsgi` Support new semantic conventions ([#299](https://github.com/open-telemetry/opentelemetry-python/pull/299)) - `opentelemetry-ext-wsgi` Updates for core library changes @@ -505,11 +541,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.2a0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v0.2.0) - 2019-10-29 ### Changed + - `opentelemetry-ext-wsgi` Updates for core library changes - `opentelemetry-ext-http-requests` Updates for core library changes ## [0.1a0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v0.1.0) - 2019-09-30 ### Added + - `opentelemetry-ext-wsgi` Initial release - `opentelemetry-ext-http-requests` Initial release From 17a0269e4c562dea413c6f7d2b85052986e7c30e Mon Sep 17 00:00:00 2001 From: Cristian Date: Sun, 2 May 2021 14:01:11 -0500 Subject: [PATCH 03/10] refactor: Rename _excluded_urls to _excluded_urls_from_env in fastapi instrumentation to make implementation more readable --- .../src/opentelemetry/instrumentation/fastapi/__init__.py | 6 +++--- .../tests/test_fastapi_instrumentation.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) 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 b14ffbff98..88e7b01df7 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py @@ -20,7 +20,7 @@ from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.util.http import get_excluded_urls -_excluded_urls = get_excluded_urls("FASTAPI") +_excluded_urls_from_env = get_excluded_urls("FASTAPI") class FastAPIInstrumentor(BaseInstrumentor): @@ -40,7 +40,7 @@ def instrument_app( """Instrument an uninstrumented FastAPI application.""" if not getattr(app, "is_instrumented_by_opentelemetry", False): if excluded_urls is None: - excluded_urls = _excluded_urls + excluded_urls = _excluded_urls_from_env app.add_middleware( OpenTelemetryMiddleware, @@ -69,7 +69,7 @@ def __init__(self, *args, **kwargs): excluded_urls = ( _InstrumentedFastAPI._excluded_urls if _InstrumentedFastAPI._excluded_urls is not None - else _excluded_urls + else _excluded_urls_from_env ) self.add_middleware( OpenTelemetryMiddleware, diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py index 1f4c699420..5e99395358 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py @@ -50,7 +50,7 @@ def setUp(self): ) self.env_patch.start() self.exclude_patch = patch( - "opentelemetry.instrumentation.fastapi._excluded_urls", + "opentelemetry.instrumentation.fastapi._excluded_urls_from_env", get_excluded_urls("FASTAPI"), ) self.exclude_patch.start() From f0471535205496e71a3d7114da1379ac7abb45ac Mon Sep 17 00:00:00 2001 From: Cristian Date: Sun, 2 May 2021 14:32:11 -0500 Subject: [PATCH 04/10] refactor: Move excluded urls logic to the _instrument function --- .../instrumentation/fastapi/__init__.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) 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 88e7b01df7..28a7a2d31e 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py @@ -53,7 +53,12 @@ def instrument_app( def _instrument(self, **kwargs): self._original_fastapi = fastapi.FastAPI _InstrumentedFastAPI._tracer_provider = kwargs.get("tracer_provider") - _InstrumentedFastAPI._excluded_urls = kwargs.get("excluded_urls") + _excluded_urls = kwargs.get("excluded_urls") + _InstrumentedFastAPI._excluded_urls = ( + _excluded_urls_from_env + if _excluded_urls is None + else _excluded_urls + ) fastapi.FastAPI = _InstrumentedFastAPI def _uninstrument(self, **kwargs): @@ -66,14 +71,9 @@ class _InstrumentedFastAPI(fastapi.FastAPI): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - excluded_urls = ( - _InstrumentedFastAPI._excluded_urls - if _InstrumentedFastAPI._excluded_urls is not None - else _excluded_urls_from_env - ) self.add_middleware( OpenTelemetryMiddleware, - excluded_urls=excluded_urls, + excluded_urls=_InstrumentedFastAPI._excluded_urls, span_details_callback=_get_route_details, tracer_provider=_InstrumentedFastAPI._tracer_provider, ) From b81dbf55bf8f5f6e843a4b4f96c8529b2c6f0029 Mon Sep 17 00:00:00 2001 From: Cristian Date: Sun, 9 May 2021 12:35:26 -0500 Subject: [PATCH 05/10] refactor: Use ExcludeList only internally in the instrumentation(fastapi) --- .../README.rst | 5 ++--- .../instrumentation/fastapi/__init__.py | 17 ++++++++++++----- .../tests/test_fastapi_instrumentation.py | 11 +++-------- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/README.rst b/instrumentation/opentelemetry-instrumentation-fastapi/README.rst index 3f174e34d0..2aa52e2537 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/README.rst +++ b/instrumentation/opentelemetry-instrumentation-fastapi/README.rst @@ -54,11 +54,10 @@ Usage You can also pass the list of urls to exclude explicitly to the instrumentation call: .. code-block:: python - from opentelemetry.util.http import ExcludeList - FastAPIInstrumentor.instrument_app(app, ExcludeList("client/.*/info,healthcheck")) + FastAPIInstrumentor.instrument_app(app, "client/.*/info,healthcheck") References ---------- * `OpenTelemetry Project `_ -* `OpenTelemetry Python Examples `_ \ No newline at end of file +* `OpenTelemetry Python Examples `_ 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 28a7a2d31e..e5fb003ce0 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py @@ -18,11 +18,18 @@ from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.semconv.trace import SpanAttributes -from opentelemetry.util.http import get_excluded_urls +from opentelemetry.util.http import get_excluded_urls, ExcludeList _excluded_urls_from_env = get_excluded_urls("FASTAPI") +def parse_urls(urls_str): + """ + Small helper to put the urls inside of ExcludeList + """ + return ExcludeList(url.strip() for url in urls_str.split(",")) + + class FastAPIInstrumentor(BaseInstrumentor): """An instrumentor for FastAPI @@ -33,14 +40,14 @@ class FastAPIInstrumentor(BaseInstrumentor): @staticmethod def instrument_app( - app: fastapi.FastAPI, - tracer_provider=None, - excluded_urls=None, + app: fastapi.FastAPI, tracer_provider=None, excluded_urls=None, ): """Instrument an uninstrumented FastAPI application.""" if not getattr(app, "is_instrumented_by_opentelemetry", False): if excluded_urls is None: excluded_urls = _excluded_urls_from_env + else: + excluded_urls = parse_urls(excluded_urls) app.add_middleware( OpenTelemetryMiddleware, @@ -57,7 +64,7 @@ def _instrument(self, **kwargs): _InstrumentedFastAPI._excluded_urls = ( _excluded_urls_from_env if _excluded_urls is None - else _excluded_urls + else parse_urls(_excluded_urls) ) fastapi.FastAPI = _InstrumentedFastAPI diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py index 5e99395358..4c4a39049b 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py @@ -22,7 +22,7 @@ from opentelemetry.sdk.resources import Resource from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.test.test_base import TestBase -from opentelemetry.util.http import get_excluded_urls, ExcludeList +from opentelemetry.util.http import get_excluded_urls class TestFastAPIManualInstrumentation(TestBase): @@ -34,12 +34,7 @@ def _create_app(self): def _create_app_explicit_excluded_urls(self): app = self._create_fastapi_app() to_exclude = "/user/123,/foobar" - excluded_urls = [ - excluded_url.strip() for excluded_url in to_exclude.split(",") - ] - self._instrumentor.instrument_app( - app, excluded_urls=ExcludeList(excluded_urls) - ) + self._instrumentor.instrument_app(app, excluded_urls=to_exclude) return app def setUp(self): @@ -160,7 +155,7 @@ def _create_app_explicit_excluded_urls(self): self._instrumentor.uninstrument() # Disable previous instrumentation (setUp) self._instrumentor.instrument( tracer_provider=tracer_provider, - excluded_urls=ExcludeList(excluded_urls), + excluded_urls=to_exclude, ) return self._create_fastapi_app() From a335531040eecfaf61b68d54624a667573b9dc6a Mon Sep 17 00:00:00 2001 From: Cristian Date: Sun, 30 May 2021 11:41:29 -0500 Subject: [PATCH 06/10] refactor: Move utils method into http-utils package --- .../opentelemetry/instrumentation/fastapi/__init__.py | 11 ++--------- .../src/opentelemetry/util/http/__init__.py | 9 ++++++++- 2 files changed, 10 insertions(+), 10 deletions(-) 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 e5fb003ce0..29dfebc01a 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py @@ -18,18 +18,11 @@ from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.semconv.trace import SpanAttributes -from opentelemetry.util.http import get_excluded_urls, ExcludeList +from opentelemetry.util.http import get_excluded_urls, parse_excluded_urls _excluded_urls_from_env = get_excluded_urls("FASTAPI") -def parse_urls(urls_str): - """ - Small helper to put the urls inside of ExcludeList - """ - return ExcludeList(url.strip() for url in urls_str.split(",")) - - class FastAPIInstrumentor(BaseInstrumentor): """An instrumentor for FastAPI @@ -47,7 +40,7 @@ def instrument_app( if excluded_urls is None: excluded_urls = _excluded_urls_from_env else: - excluded_urls = parse_urls(excluded_urls) + excluded_urls = parse_excluded_urls(excluded_urls) app.add_middleware( OpenTelemetryMiddleware, diff --git a/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py b/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py index 068511010d..4f6b27698e 100644 --- a/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py +++ b/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py @@ -13,7 +13,7 @@ # limitations under the License. from os import environ -from re import compile as re_compile +from re import I, compile as re_compile from re import search @@ -51,6 +51,13 @@ def get_excluded_urls(instrumentation): _root.format("{}_EXCLUDED_URLS".format(instrumentation)), [] ) + return parse_excluded_urls(excluded_urls) + + +def parse_excluded_urls(excluded_urls): + """ + Small helper to put an arbitrary url list inside of ExcludeList + """ if excluded_urls: excluded_urls = [ excluded_url.strip() for excluded_url in excluded_urls.split(",") From 34fa7274cc0b3dd82db0b285561dafe2ba975cf0 Mon Sep 17 00:00:00 2001 From: Cristian Date: Sun, 30 May 2021 11:47:07 -0500 Subject: [PATCH 07/10] test: Remove unneeded variable in explicit excluded_urls test --- .../tests/test_fastapi_instrumentation.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py index 4c4a39049b..e3e6f8f4c5 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py @@ -149,13 +149,9 @@ def _create_app_explicit_excluded_urls(self): self.memory_exporter = exporter to_exclude = "/user/123,/foobar" - excluded_urls = [ - excluded_url.strip() for excluded_url in to_exclude.split(",") - ] self._instrumentor.uninstrument() # Disable previous instrumentation (setUp) self._instrumentor.instrument( - tracer_provider=tracer_provider, - excluded_urls=to_exclude, + tracer_provider=tracer_provider, excluded_urls=to_exclude, ) return self._create_fastapi_app() From b659f080c6dd7e1046cc9a21291bb10a1cd9bdcd Mon Sep 17 00:00:00 2001 From: Cristian Vargas Date: Sun, 30 May 2021 11:49:02 -0500 Subject: [PATCH 08/10] fix: Resolve docs generation issue Co-authored-by: Diego Hurtado --- instrumentation/opentelemetry-instrumentation-fastapi/README.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/README.rst b/instrumentation/opentelemetry-instrumentation-fastapi/README.rst index 2aa52e2537..949cc18708 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/README.rst +++ b/instrumentation/opentelemetry-instrumentation-fastapi/README.rst @@ -54,6 +54,7 @@ Usage You can also pass the list of urls to exclude explicitly to the instrumentation call: .. code-block:: python + FastAPIInstrumentor.instrument_app(app, "client/.*/info,healthcheck") References From 180031eeb0ec3dfd1c62dd5f8b3d79c366fea035 Mon Sep 17 00:00:00 2001 From: Cristian Date: Sun, 30 May 2021 19:48:54 -0500 Subject: [PATCH 09/10] fix: Remove unneeded import --- .../src/opentelemetry/util/http/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py b/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py index 4f6b27698e..a10a307d80 100644 --- a/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py +++ b/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py @@ -13,7 +13,7 @@ # limitations under the License. from os import environ -from re import I, compile as re_compile +from re import compile as re_compile from re import search From 02fa810e428bf42f49886ce1f2953ef80b37898c Mon Sep 17 00:00:00 2001 From: Cristian Date: Sun, 13 Jun 2021 10:39:14 -0500 Subject: [PATCH 10/10] fix: wrong variable name in fastapi instrumentation --- .../src/opentelemetry/instrumentation/fastapi/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 befa4f6a9f..933b027018 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py @@ -63,7 +63,7 @@ def _instrument(self, **kwargs): _InstrumentedFastAPI._excluded_urls = ( _excluded_urls_from_env if _excluded_urls is None - else parse_urls(_excluded_urls) + else parse_excluded_urls(_excluded_urls) ) fastapi.FastAPI = _InstrumentedFastAPI