diff --git a/CHANGELOG.md b/CHANGELOG.md index 32d76f53ad..0c1311c7a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased](https://github.com/open-telemetry/opentelemetry-python/compare/v1.6.2-0.25b2...HEAD) + ### Fixed - `opentelemetry-instrumentation-asgi` now explicitly depends on asgiref as it uses the package instead of instrumenting it. @@ -19,6 +20,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#753](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/753)) - `opentelemetry-instrumentation-pika` Add `_decorate_basic_consume` to ensure post instrumentation `basic_consume` calls are also instrumented. ([#759](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/759)) +- Consolidate instrumentation documentation in docstrings + ([#754](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/754)) ### Fixed diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/README.rst b/instrumentation/opentelemetry-instrumentation-aiohttp-client/README.rst index a43d41c844..eb2a3f9505 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/README.rst +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/README.rst @@ -16,45 +16,6 @@ Installation pip install opentelemetry-instrumentation-aiohttp-client - -Example -------- - -.. code:: python - - import asyncio - - import aiohttp - - from opentelemetry.instrumentation.aiohttp_client import AioHttpClientInstrumentor - from opentelemetry import trace - from opentelemetry.exporter.jaeger.thrift import JaegerExporter - from opentelemetry.sdk.trace import TracerProvider - from opentelemetry.sdk.trace.export import BatchSpanProcessor - - - _JAEGER_EXPORTER = JaegerExporter( - service_name="example-xxx", - agent_host_name="localhost", - agent_port=6831, - ) - - _TRACE_PROVIDER = TracerProvider() - _TRACE_PROVIDER.add_span_processor(BatchSpanProcessor(_JAEGER_EXPORTER)) - trace.set_tracer_provider(_TRACE_PROVIDER) - - AioHttpClientInstrumentor().instrument() - - - async def span_emitter(): - async with aiohttp.ClientSession() as session: - async with session.get("https://example.com") as resp: - print(resp.status) - - - asyncio.run(span_emitter()) - - References ---------- diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/__init__.py b/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/__init__.py index eba8a41501..a89b3a2220 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/__init__.py @@ -58,6 +58,29 @@ def strip_query_params(url: yarl.URL) -> str: async with session.get(url) as response: await response.text() +Configuration +------------- + +Request/Response hooks +********************** + +Utilize request/reponse hooks to execute custom logic to be performed before/after performing a request. + +.. code-block:: python + + def request_hook(span: Span, params: aiohttp.TraceRequestStartParams): + if span and span.is_recording(): + span.set_attribute("custom_user_attribute_from_request_hook", "some-value") + + def response_hook(span: Span, params: typing.Union[ + aiohttp.TraceRequestEndParams, + aiohttp.TraceRequestExceptionParams, + ]): + if span and span.is_recording(): + span.set_attribute("custom_user_attribute_from_response_hook", "some-value") + + AioHttpClientInstrumentor().instrument(request_hook=request_hook, response_hook=response_hook) + API --- """ diff --git a/instrumentation/opentelemetry-instrumentation-asgi/README.rst b/instrumentation/opentelemetry-instrumentation-asgi/README.rst index 780bf0d70c..5abd88a161 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/README.rst +++ b/instrumentation/opentelemetry-instrumentation-asgi/README.rst @@ -17,54 +17,6 @@ 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 ---------- 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 7bbf23e407..df7af306d7 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py @@ -16,6 +16,82 @@ 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. + +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) + + +Configuration +------------- + +Request/Response hooks +********************** + +Utilize request/reponse hooks to execute custom logic to be performed before/after performing a request. The server request hook takes in a server span and ASGI +scope object for every incoming request. The client request hook is called with the internal span and an ASGI scope which is sent as a dictionary for when the method recieve is called. +The client response hook is called with the internal span and an ASGI event which is sent as a dictionary for when the method send is called. + +.. code-block:: python + + def server_request_hook(span: Span, scope: dict): + if span and span.is_recording(): + span.set_attribute("custom_user_attribute_from_request_hook", "some-value") + + def client_request_hook(span: Span, scope: dict): + if span and span.is_recording(): + span.set_attribute("custom_user_attribute_from_client_request_hook", "some-value") + + def client_response_hook(span: Span, message: dict): + if span and span.is_recording(): + span.set_attribute("custom_user_attribute_from_response_hook", "some-value") + + OpenTelemetryMiddleware().(application, server_request_hook=server_request_hook, client_request_hook=client_request_hook, client_response_hook=client_response_hook) + +API +--- """ import typing diff --git a/instrumentation/opentelemetry-instrumentation-celery/README.rst b/instrumentation/opentelemetry-instrumentation-celery/README.rst index b8afafa6f3..216fa0db93 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/README.rst +++ b/instrumentation/opentelemetry-instrumentation-celery/README.rst @@ -16,51 +16,6 @@ Installation pip install opentelemetry-instrumentation-celery -Usage ------ - -* Start broker backend - -:: - docker run -p 5672:5672 rabbitmq - - -* Run instrumented task - -.. code-block:: python - - from opentelemetry import trace - from opentelemetry.sdk.trace import TracerProvider - from opentelemetry.sdk.trace.export import BatchSpanProcessor - from opentelemetry.instrumentation.celery import CeleryInstrumentor - - from celery import Celery - from celery.signals import worker_process_init - - @worker_process_init.connect(weak=False) - def init_celery_tracing(*args, **kwargs): - trace.set_tracer_provider(TracerProvider()) - span_processor = BatchSpanProcessor(ConsoleSpanExporter()) - trace.get_tracer_provider().add_span_processor(span_processor) - CeleryInstrumentor().instrument() - - app = Celery("tasks", broker="amqp://localhost") - - @app.task - def add(x, y): - return x + y - - add.delay(42, 50) - - -Setting up tracing --------------------- - -When tracing a celery worker process, tracing and instrumention both must be initialized after the celery worker -process is initialized. This is required for any tracing components that might use threading to work correctly -such as the BatchSpanProcessor. Celery provides a signal called ``worker_process_init`` that can be used to -accomplish this as shown in the example above. - References ---------- * `OpenTelemetry Celery Instrumentation `_ diff --git a/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/__init__.py b/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/__init__.py index b40642eeff..6d79f45115 100644 --- a/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/__init__.py @@ -47,6 +47,14 @@ def add(x, y): add.delay(42, 50) +Setting up tracing +------------------ + +When tracing a celery worker process, tracing and instrumention both must be initialized after the celery worker +process is initialized. This is required for any tracing components that might use threading to work correctly +such as the BatchSpanProcessor. Celery provides a signal called ``worker_process_init`` that can be used to +accomplish this as shown in the example above. + API --- """ diff --git a/instrumentation/opentelemetry-instrumentation-django/README.rst b/instrumentation/opentelemetry-instrumentation-django/README.rst index ccb8ebbcf7..bada056b7d 100644 --- a/instrumentation/opentelemetry-instrumentation-django/README.rst +++ b/instrumentation/opentelemetry-instrumentation-django/README.rst @@ -15,52 +15,6 @@ Installation pip install opentelemetry-instrumentation-django -Configuration -------------- - -Exclude lists -************* -To exclude certain URLs from being tracked, set the environment variable ``OTEL_PYTHON_DJANGO_EXCLUDED_URLS`` with comma delimited regexes representing which URLs to exclude. - -For example, - -:: - - export OTEL_PYTHON_DJANGO_EXCLUDED_URLS="client/.*/info,healthcheck" - -will exclude requests such as ``https://site/client/123/info`` and ``https://site/xyz/healthcheck``. - -Request attributes -******************** -To extract certain attributes from Django's request object and use them as span attributes, set the environment variable ``OTEL_PYTHON_DJANGO_TRACED_REQUEST_ATTRS`` to a comma -delimited list of request attribute names. - -For example, - -:: - - export OTEL_PYTHON_DJANGO_TRACED_REQUEST_ATTRS='path_info,content_type' - -will extract path_info and content_type attributes from every traced request and add them as span attritbues. - -Django Request object reference: https://docs.djangoproject.com/en/3.1/ref/request-response/#attributes - -Request and Response hooks -*************************** -The instrumentation supports specifying request and response hooks. These are functions that get called back by the instrumentation right after a Span is created for a request -and right before the span is finished while processing a response. The hooks can be configured as follows: - -:: - - def request_hook(span, request): - pass - - def response_hook(span, request, response): - pass - - DjangoInstrumentation().instrument(request_hook=request_hook, response_hook=response_hook) - - References ---------- 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 ffecf70bab..344fbb261c 100644 --- a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/__init__.py @@ -71,6 +71,12 @@ def response_hook(span, request, response): pass DjangoInstrumentation().instrument(request_hook=request_hook, response_hook=response_hook) + +Django Request object: https://docs.djangoproject.com/en/3.1/ref/request-response/#httprequest-objects +Django Response object: https://docs.djangoproject.com/en/3.1/ref/request-response/#httpresponse-objects + +API +--- """ from logging import getLogger diff --git a/instrumentation/opentelemetry-instrumentation-elasticsearch/src/opentelemetry/instrumentation/elasticsearch/__init__.py b/instrumentation/opentelemetry-instrumentation-elasticsearch/src/opentelemetry/instrumentation/elasticsearch/__init__.py index 232877741d..44763fa9f7 100644 --- a/instrumentation/opentelemetry-instrumentation-elasticsearch/src/opentelemetry/instrumentation/elasticsearch/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-elasticsearch/src/opentelemetry/instrumentation/elasticsearch/__init__.py @@ -33,9 +33,6 @@ es.index(index='my-index', doc_type='my-type', id=1, body={'my': 'data', 'timestamp': datetime.now()}) es.get(index='my-index', doc_type='my-type', id=1) -API ---- - Elasticsearch instrumentation prefixes operation names with the string "Elasticsearch". This can be changed to a different string by either setting the `OTEL_PYTHON_ELASTICSEARCH_NAME_PREFIX` environment variable or by passing the prefix as an argument to the instrumentor. For example, @@ -79,6 +76,9 @@ def response_hook(span, response): es = elasticsearch.Elasticsearch() es.index(index='my-index', doc_type='my-type', id=1, body={'my': 'data', 'timestamp': datetime.now()}) es.get(index='my-index', doc_type='my-type', id=1) + +API +--- """ import re diff --git a/instrumentation/opentelemetry-instrumentation-falcon/README.rst b/instrumentation/opentelemetry-instrumentation-falcon/README.rst index c192a2ae78..b4756f507d 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/README.rst +++ b/instrumentation/opentelemetry-instrumentation-falcon/README.rst @@ -46,6 +46,22 @@ will extract path_info and content_type attributes from every traced request and Falcon Request object reference: https://falcon.readthedocs.io/en/stable/api/request_and_response.html#id1 + +Request/Response hooks +********************** +The instrumentation supports specifying request and response hooks. These are functions that get called back by the instrumentation right after a Span is created for a request +and right before the span is finished while processing a response. The hooks can be configured as follows: + +:: + + def request_hook(span, req): + pass + + def response_hook(span, req, resp): + pass + + FalconInstrumentation().instrument(request_hook=request_hook, response_hook=response_hook) + References ---------- diff --git a/instrumentation/opentelemetry-instrumentation-fastapi/README.rst b/instrumentation/opentelemetry-instrumentation-fastapi/README.rst index f50240fc77..ac4419f0ab 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/README.rst +++ b/instrumentation/opentelemetry-instrumentation-fastapi/README.rst @@ -19,44 +19,6 @@ Installation pip install opentelemetry-instrumentation-fastapi -Configuration -------------- - -Exclude lists -************* -To exclude certain URLs from being tracked, set the environment variable ``OTEL_PYTHON_FASTAPI_EXCLUDED_URLS`` with comma delimited regexes representing which URLs to exclude. - -For example, - -:: - - export OTEL_PYTHON_FASTAPI_EXCLUDED_URLS="client/.*/info,healthcheck" - -will exclude requests such as ``https://site/client/123/info`` and ``https://site/xyz/healthcheck``. - - -Usage ------ - -.. code-block:: python - - import fastapi - from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor - - app = fastapi.FastAPI() - - @app.get("/foobar") - async def foobar(): - return {"message": "hello world"} - - FastAPIInstrumentor.instrument_app(app) - -You can also pass the list of urls to exclude explicitly to the instrumentation call: - -.. code-block:: python - - FastAPIInstrumentor.instrument_app(app, excluded_urls="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 3851e3c10b..08cfab9140 100644 --- a/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py @@ -12,6 +12,70 @@ # See the License for the specific language governing permissions and # limitations under the License. +""" +Usage +----- + +.. code-block:: python + + import fastapi + from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor + + app = fastapi.FastAPI() + + @app.get("/foobar") + async def foobar(): + return {"message": "hello world"} + + FastAPIInstrumentor.instrument_app(app) + +Configuration +------------- + +Exclude lists +************* +To exclude certain URLs from being tracked, set the environment variable ``OTEL_PYTHON_FASTAPI_EXCLUDED_URLS`` with comma delimited regexes representing which URLs to exclude. + +For example, + +:: + + export OTEL_PYTHON_FASTAPI_EXCLUDED_URLS="client/.*/info,healthcheck" + +will exclude requests such as ``https://site/client/123/info`` and ``https://site/xyz/healthcheck``. + +You can also pass the comma delimited regexes to the ``instrument_app`` method directly: + +.. code-block:: python + + FastAPIInstrumentor.instrument_app(app, excluded_urls="client/.*/info,healthcheck") + +Request/Response hooks +********************** + +Utilize request/reponse hooks to execute custom logic to be performed before/after performing a request. The server request hook takes in a server span and ASGI +scope object for every incoming request. The client request hook is called with the internal span and an ASGI scope which is sent as a dictionary for when the method recieve is called. +The client response hook is called with the internal span and an ASGI event which is sent as a dictionary for when the method send is called. + +.. code-block:: python + + def server_request_hook(span: Span, scope: dict): + if span and span.is_recording(): + span.set_attribute("custom_user_attribute_from_request_hook", "some-value") + + def client_request_hook(span: Span, scope: dict): + if span and span.is_recording(): + span.set_attribute("custom_user_attribute_from_client_request_hook", "some-value") + + def client_response_hook(span: Span, message: dict): + if span and span.is_recording(): + span.set_attribute("custom_user_attribute_from_response_hook", "some-value") + + FastAPIInstrumentor().instrument(server_request_hook=server_request_hook, client_request_hook=client_request_hook, client_response_hook=client_response_hook) + +API +--- +""" import logging import typing from typing import Collection diff --git a/instrumentation/opentelemetry-instrumentation-flask/README.rst b/instrumentation/opentelemetry-instrumentation-flask/README.rst index a139ab2683..cb1f69ee6f 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/README.rst +++ b/instrumentation/opentelemetry-instrumentation-flask/README.rst @@ -37,6 +37,26 @@ You can also pass the comma delimited regexes to the ``instrument_app`` method d FlaskInstrumentor().instrument_app(app, excluded_urls="client/.*/info,healthcheck") +Request/Response hooks +********************** + +Utilize request/reponse hooks to execute custom logic to be performed before/after performing a request. Environ is an instance of WSGIEnvironment (flask.request.environ). +Response_headers is a list of key-value (tuples) representing the response headers returned from the response. + +.. code-block:: python + + def request_hook(span: Span, environ: WSGIEnvironment): + if span and span.is_recording(): + span.set_attribute("custom_user_attribute_from_request_hook", "some-value") + + def response_hook(span: Span, status: str, response_headers: List): + if span and span.is_recording(): + span.set_attribute("custom_user_attribute_from_response_hook", "some-value") + + FlaskInstrumentation().instrument(request_hook=request_hook, response_hook=response_hook) + +Flask Request object reference: https://flask.palletsprojects.com/en/2.0.x/api/#flask.Request + References ---------- 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 3897288937..7466542a0d 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py @@ -43,6 +43,47 @@ def hello(): if __name__ == "__main__": app.run(debug=True) +Configuration +------------- + +Exclude lists +************* +To exclude certain URLs from being tracked, set the environment variable ``OTEL_PYTHON_FLASK_EXCLUDED_URLS`` with comma delimited regexes representing which URLs to exclude. + +For example, + +:: + + export OTEL_PYTHON_FLASK_EXCLUDED_URLS="client/.*/info,healthcheck" + +will exclude requests such as ``https://site/client/123/info`` and ``https://site/xyz/healthcheck``. + +You can also pass the comma delimited regexes to the ``instrument_app`` method directly: + +.. code-block:: python + + FlaskInstrumentor().instrument_app(app, excluded_urls="client/.*/info,healthcheck") + +Request/Response hooks +********************** + +Utilize request/reponse hooks to execute custom logic to be performed before/after performing a request. Environ is an instance of WSGIEnvironment (flask.request.environ). +Response_headers is a list of key-value (tuples) representing the response headers returned from the response. + +.. code-block:: python + + def request_hook(span: Span, environ: WSGIEnvironment): + if span and span.is_recording(): + span.set_attribute("custom_user_attribute_from_request_hook", "some-value") + + def response_hook(span: Span, status: str, response_headers: List): + if span and span.is_recording(): + span.set_attribute("custom_user_attribute_from_response_hook", "some-value") + + FlaskInstrumentation().instrument(request_hook=request_hook, response_hook=response_hook) + +Flask Request object reference: https://flask.palletsprojects.com/en/2.0.x/api/#flask.Request + API --- """ diff --git a/instrumentation/opentelemetry-instrumentation-httpx/README.rst b/instrumentation/opentelemetry-instrumentation-httpx/README.rst index 722f1d2bea..ffa86cb4bc 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/README.rst +++ b/instrumentation/opentelemetry-instrumentation-httpx/README.rst @@ -69,17 +69,17 @@ If you need to uninstrument clients, there are two options available. .. code-block:: python - import httpx - from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentor + import httpx + from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentor - HTTPXClientInstrumentor().instrument() - client = httpx.Client() + HTTPXClientInstrumentor().instrument() + client = httpx.Client() + + # Uninstrument a specific client + HTTPXClientInstrumentor.uninstrument_client(client) - # Uninstrument a specific client - HTTPXClientInstrumentor.uninstrument_client(client) - - # Uninstrument all clients - HTTPXClientInstrumentor().uninstrument() + # Uninstrument all clients + HTTPXClientInstrumentor().uninstrument() Using transports directly diff --git a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py index a180d65726..202f7ebf8a 100644 --- a/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py @@ -11,7 +11,155 @@ # 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. +""" +Usage +----- +Instrumenting all clients +************************* + +When using the instrumentor, all clients will automatically trace requests. + +.. code-block:: python + + import httpx + from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentor + + url = "https://httpbin.org/get" + HTTPXClientInstrumentor().instrument() + + with httpx.Client() as client: + response = client.get(url) + + async with httpx.AsyncClient() as client: + response = await client.get(url) + +Instrumenting single clients +**************************** + +If you only want to instrument requests for specific client instances, you can +use the `instrument_client` method. + + +.. code-block:: python + + import httpx + from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentor + + url = "https://httpbin.org/get" + + with httpx.Client(transport=telemetry_transport) as client: + HTTPXClientInstrumentor.instrument_client(client) + response = client.get(url) + + async with httpx.AsyncClient(transport=telemetry_transport) as client: + HTTPXClientInstrumentor.instrument_client(client) + response = await client.get(url) + + +Uninstrument +************ + +If you need to uninstrument clients, there are two options available. + +.. code-block:: python + + import httpx + from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentor + + HTTPXClientInstrumentor().instrument() + client = httpx.Client() + + # Uninstrument a specific client + HTTPXClientInstrumentor.uninstrument_client(client) + + # Uninstrument all clients + HTTPXClientInstrumentor().uninstrument() + + +Using transports directly +************************* + +If you don't want to use the instrumentor class, you can use the transport classes directly. + + +.. code-block:: python + + import httpx + from opentelemetry.instrumentation.httpx import ( + AsyncOpenTelemetryTransport, + SyncOpenTelemetryTransport, + ) + + url = "https://httpbin.org/get" + transport = httpx.HTTPTransport() + telemetry_transport = SyncOpenTelemetryTransport(transport) + + with httpx.Client(transport=telemetry_transport) as client: + response = client.get(url) + + transport = httpx.AsyncHTTPTransport() + telemetry_transport = AsyncOpenTelemetryTransport(transport) + + async with httpx.AsyncClient(transport=telemetry_transport) as client: + response = await client.get(url) + + +Request and response hooks +*************************** + +The instrumentation supports specifying request and response hooks. These are functions that get called back by the instrumentation right after a span is created for a request +and right before the span is finished while processing a response. + +.. note:: + + The request hook receives the raw arguments provided to the transport layer. The response hook receives the raw return values from the transport layer. + +The hooks can be configured as follows: + + +.. code-block:: python + + from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentor + + def request_hook(span, request): + # method, url, headers, stream, extensions = request + pass + + def response_hook(span, request, response): + # method, url, headers, stream, extensions = request + # status_code, headers, stream, extensions = response + pass + + HTTPXClientInstrumentor().instrument(request_hook=request_hook, response_hook=response_hook) + + +Or if you are using the transport classes directly: + + +.. code-block:: python + + from opentelemetry.instrumentation.httpx import SyncOpenTelemetryTransport + + def request_hook(span, request): + # method, url, headers, stream, extensions = request + pass + + def response_hook(span, request, response): + # method, url, headers, stream, extensions = request + # status_code, headers, stream, extensions = response + pass + + transport = httpx.HTTPTransport() + telemetry_transport = SyncOpenTelemetryTransport( + transport, + request_hook=request_hook, + response_hook=response_hook + ) + +API +--- +""" import logging import typing diff --git a/instrumentation/opentelemetry-instrumentation-pika/README.rst b/instrumentation/opentelemetry-instrumentation-pika/README.rst index 0f6ab3fd78..e4da7844b5 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/README.rst +++ b/instrumentation/opentelemetry-instrumentation-pika/README.rst @@ -15,54 +15,6 @@ Installation pip install opentelemetry-instrumentation-pika -Usage ------ - -* Start broker backend - -.. code-block:: python - - docker run -p 5672:5672 rabbitmq - -* Run instrumented task - -.. code-block:: python - - import pika - from opentelemetry.instrumentation.pika import PikaInstrumentor - - PikaInstrumentor().instrument() - - connection = pika.BlockingConnection(pika.URLParameters('amqp://localhost')) - channel = connection.channel() - channel.queue_declare(queue='hello') - channel.basic_publish(exchange='', routing_key='hello', body=b'Hello World!') - -* PikaInstrumentor also supports instrumentation of a single channel - -.. code-block:: python - - import pika - from opentelemetry.instrumentation.pika import PikaInstrumentor - - connection = pika.BlockingConnection(pika.URLParameters('amqp://localhost')) - channel = connection.channel() - channel.queue_declare(queue='hello') - - pika_instrumentation = PikaInstrumentor() - pika_instrumentation.instrument_channel(channel=channel) - - - channel.basic_publish(exchange='', routing_key='hello', body=b'Hello World!') - - pika_instrumentation.uninstrument_channel(channel=channel) - -* PikaInstrumentor also supports instrumentation without creating an object, and receiving a tracer_provider - -.. code-block:: python - - PikaInstrumentor.instrument_channel(channel, tracer_provider=tracer_provider) - References ---------- diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/README.rst b/instrumentation/opentelemetry-instrumentation-pyramid/README.rst index 5e0b114bde..cad6be04e1 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/README.rst +++ b/instrumentation/opentelemetry-instrumentation-pyramid/README.rst @@ -13,18 +13,6 @@ Installation pip install opentelemetry-instrumentation-pyramid -Exclude lists -************* -To exclude certain URLs from being tracked, set the environment variable ``OTEL_PYTHON_PYRAMID_EXCLUDED_URLS`` with comma delimited regexes representing which URLs to exclude. - -For example, - -:: - - export OTEL_PYTHON_PYRAMID_EXCLUDED_URLS="client/.*/info,healthcheck" - -will exclude requests such as ``https://site/client/123/info`` and ``https://site/xyz/healthcheck``. - References ---------- * `OpenTelemetry Pyramid Instrumentation `_ diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/__init__.py b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/__init__.py index 7f7f88d03c..dd8e620baf 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/__init__.py @@ -74,6 +74,21 @@ # use your config as normal. config.add_route('index', '/') +Configuration +------------- + +Exclude lists +************* +To exclude certain URLs from being tracked, set the environment variable ``OTEL_PYTHON_PYRAMID_EXCLUDED_URLS`` with comma delimited regexes representing which URLs to exclude. + +For example, + +:: + + export OTEL_PYTHON_PYRAMID_EXCLUDED_URLS="client/.*/info,healthcheck" + +will exclude requests such as ``https://site/client/123/info`` and ``https://site/xyz/healthcheck``. + API --- """ diff --git a/instrumentation/opentelemetry-instrumentation-redis/README.rst b/instrumentation/opentelemetry-instrumentation-redis/README.rst index cae4635613..1e381024ab 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/README.rst +++ b/instrumentation/opentelemetry-instrumentation-redis/README.rst @@ -15,7 +15,6 @@ Installation pip install opentelemetry-instrumentation-redis - References ---------- diff --git a/instrumentation/opentelemetry-instrumentation-requests/README.rst b/instrumentation/opentelemetry-instrumentation-requests/README.rst index 57cc6ee525..4163725b16 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/README.rst +++ b/instrumentation/opentelemetry-instrumentation-requests/README.rst @@ -19,11 +19,17 @@ Installation Configuration ------------- -.. code-block:: python +Exclude lists +************* +To exclude certain URLs from being tracked, set the environment variable ``OTEL_PYTHON_REQUESTS_EXCLUDED_URLS`` with comma delimited regexes representing which URLs to exclude. - from opentelemetry.instrumentation.requests import RequestsInstrumentor - RequestsInstrumentor().instrument() +For example, +:: + + export OTEL_PYTHON_REQUESTS_EXCLUDED_URLS="client/.*/info,healthcheck" + +will exclude requests such as ``https://site/client/123/info`` and ``https://site/xyz/healthcheck``. References ---------- diff --git a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py index c7223dbb13..7a8988dda3 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py @@ -28,6 +28,21 @@ RequestsInstrumentor().instrument() response = requests.get(url="https://www.example.org/") +Configuration +------------- + +Exclude lists +************* +To exclude certain URLs from being tracked, set the environment variable ``OTEL_PYTHON_REQUESTS_EXCLUDED_URLS`` with comma delimited regexes representing which URLs to exclude. + +For example, + +:: + + export OTEL_PYTHON_REQUESTS_EXCLUDED_URLS="client/.*/info,healthcheck" + +will exclude requests such as ``https://site/client/123/info`` and ``https://site/xyz/healthcheck``. + API --- """ diff --git a/instrumentation/opentelemetry-instrumentation-starlette/README.rst b/instrumentation/opentelemetry-instrumentation-starlette/README.rst index 83962e0475..cf8a263fc8 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/README.rst +++ b/instrumentation/opentelemetry-instrumentation-starlette/README.rst @@ -19,41 +19,6 @@ Installation pip install opentelemetry-instrumentation-starlette -Configuration -------------- - -Exclude lists -************* -To exclude certain URLs from being tracked, set the environment variable ``OTEL_PYTHON_STARLETTE_EXCLUDED_URLS`` with comma delimited regexes representing which URLs to exclude. - -For example, - -:: - - export OTEL_PYTHON_STARLETTE_EXCLUDED_URLS="client/.*/info,healthcheck" - -will exclude requests such as ``https://site/client/123/info`` and ``https://site/xyz/healthcheck``. - - -Usage ------ - -.. code-block:: python - - from opentelemetry.instrumentation.starlette import StarletteInstrumentor - from starlette import applications - from starlette.responses import PlainTextResponse - from starlette.routing import Route - - def home(request): - return PlainTextResponse("hi") - - app = applications.Starlette( - routes=[Route("/foobar", home)] - ) - StarletteInstrumentor.instrument_app(app) - - References ---------- 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 90e0ab05f7..ddbf056d33 100644 --- a/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-starlette/src/opentelemetry/instrumentation/starlette/__init__.py @@ -12,6 +12,64 @@ # See the License for the specific language governing permissions and # limitations under the License. +""" +Usage +----- + +.. code-block:: python + + from opentelemetry.instrumentation.starlette import StarletteInstrumentor + from starlette import applications + from starlette.responses import PlainTextResponse + from starlette.routing import Route + + def home(request): + return PlainTextResponse("hi") + + app = applications.Starlette( + routes=[Route("/foobar", home)] + ) + StarletteInstrumentor.instrument_app(app) + +Configuration +------------- + +Exclude lists +************* +To exclude certain URLs from being tracked, set the environment variable ``OTEL_PYTHON_STARLETTE_EXCLUDED_URLS`` with comma delimited regexes representing which URLs to exclude. + +For example, + +:: + + export OTEL_PYTHON_STARLETTE_EXCLUDED_URLS="client/.*/info,healthcheck" + +will exclude requests such as ``https://site/client/123/info`` and ``https://site/xyz/healthcheck``. + +Request/Response hooks +********************** + +Utilize request/reponse hooks to execute custom logic to be performed before/after performing a request. The server request hook takes in a server span and ASGI +scope object for every incoming request. The client request hook is called with the internal span and an ASGI scope which is sent as a dictionary for when the method recieve is called. +The client response hook is called with the internal span and an ASGI event which is sent as a dictionary for when the method send is called. + +.. code-block:: python + + def server_request_hook(span: Span, scope: dict): + if span and span.is_recording(): + span.set_attribute("custom_user_attribute_from_request_hook", "some-value") + def client_request_hook(span: Span, scope: dict): + if span and span.is_recording(): + span.set_attribute("custom_user_attribute_from_client_request_hook", "some-value") + def client_response_hook(span: Span, message: dict): + if span and span.is_recording(): + span.set_attribute("custom_user_attribute_from_response_hook", "some-value") + + StarletteInstrumentor().instrument(server_request_hook=server_request_hook, client_request_hook=client_request_hook, client_response_hook=client_response_hook) + +API +--- +""" import typing from typing import Collection diff --git a/instrumentation/opentelemetry-instrumentation-tornado/README.rst b/instrumentation/opentelemetry-instrumentation-tornado/README.rst index 2bbee0f573..3d5e5b9c0e 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/README.rst +++ b/instrumentation/opentelemetry-instrumentation-tornado/README.rst @@ -16,34 +16,6 @@ Installation pip install opentelemetry-instrumentation-tornado -Configuration -------------- - -The following environment variables are supported as configuration options: - -- OTEL_PYTHON_TORNADO_EXCLUDED_URLS - -A comma separated list of paths that should not be automatically traced. For example, if this is set to - -:: - - export OTEL_PYTHON_TORNADO_EXLUDED_URLS='/healthz,/ping' - -Then any requests made to ``/healthz`` and ``/ping`` will not be automatically traced. - -Request attributes -******************** -To extract certain attributes from Tornado's request object and use them as span attributes, set the environment variable ``OTEL_PYTHON_TORNADO_TRACED_REQUEST_ATTRS`` to a comma -delimited list of request attribute names. - -For example, - -:: - - export OTEL_PYTHON_TORNADO_TRACED_REQUEST_ATTRS='uri,query' - -will extract path_info and content_type attributes from every traced request and add them as span attributes. - References ---------- 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 2e3c21a813..9e99b67104 100644 --- a/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/__init__.py @@ -34,8 +34,36 @@ def get(self): app.listen(8080) tornado.ioloop.IOLoop.current().start() -Hooks -******* +Configuration +------------- + +The following environment variables are supported as configuration options: + +- OTEL_PYTHON_TORNADO_EXCLUDED_URLS + +A comma separated list of paths that should not be automatically traced. For example, if this is set to + +:: + + export OTEL_PYTHON_TORNADO_EXLUDED_URLS='/healthz,/ping' + +Then any requests made to ``/healthz`` and ``/ping`` will not be automatically traced. + +Request attributes +******************** +To extract certain attributes from Tornado's request object and use them as span attributes, set the environment variable ``OTEL_PYTHON_TORNADO_TRACED_REQUEST_ATTRS`` to a comma +delimited list of request attribute names. + +For example, + +:: + + export OTEL_PYTHON_TORNADO_TRACED_REQUEST_ATTRS='uri,query' + +will extract path_info and content_type attributes from every traced request and add them as span attributes. + +Request/Response hooks +********************** Tornado instrumentation supports extending tracing behaviour with the help of hooks. Its ``instrument()`` method accepts three optional functions that get called back with the diff --git a/instrumentation/opentelemetry-instrumentation-urllib/README.rst b/instrumentation/opentelemetry-instrumentation-urllib/README.rst index f5ab20b514..aa25fbf383 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/README.rst +++ b/instrumentation/opentelemetry-instrumentation-urllib/README.rst @@ -1,5 +1,5 @@ OpenTelemetry urllib Instrumentation -====================================== +==================================== |pypi| diff --git a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py index e0ce95d9c4..43e1997e61 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py @@ -32,8 +32,11 @@ req = request.Request('https://postman-echo.com/post', method="POST") r = request.urlopen(req) -Hooks -******* +Configuration +------------- + +Request/Response hooks +********************** The urllib instrumentation supports extending tracing behavior with the help of request and response hooks. These are functions that are called back by the instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/README.rst b/instrumentation/opentelemetry-instrumentation-urllib3/README.rst index 5c4745a3f9..61817d631f 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/README.rst +++ b/instrumentation/opentelemetry-instrumentation-urllib3/README.rst @@ -16,6 +16,32 @@ Installation pip install opentelemetry-instrumentation-urllib3 +Configuration +------------- + +Request/Response hooks +********************** + +The urllib3 instrumentation supports extending tracing behavior with the help of +request and response hooks. These are functions that are called back by the instrumentation +right after a Span is created for a request and right before the span is finished processing a response respectively. +The hooks can be configured as follows: + +.. code:: python + + # `request` is an instance of urllib3.connectionpool.HTTPConnectionPool + def request_hook(span, request): + pass + + # `request` is an instance of urllib3.connectionpool.HTTPConnectionPool + # `response` is an instance of urllib3.response.HTTPResponse + def response_hook(span, request, response): + pass + + URLLib3Instrumentor.instrument( + request_hook=request_hook, response_hook=response_hook) + ) + References ---------- diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py index 235c5b477b..ef04b7d0c2 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py @@ -34,8 +34,11 @@ def strip_query_params(url: str) -> str: http = urllib3.PoolManager() response = http.request("GET", "https://www.example.org/") -Hooks -******* +Configuration +------------- + +Request/Response hooks +********************** The urllib3 instrumentation supports extending tracing behavior with the help of request and response hooks. These are functions that are called back by the instrumentation diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/README.rst b/instrumentation/opentelemetry-instrumentation-wsgi/README.rst index d8962f1b90..5aa28e89bd 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/README.rst +++ b/instrumentation/opentelemetry-instrumentation-wsgi/README.rst @@ -17,7 +17,6 @@ Installation pip install opentelemetry-instrumentation-wsgi - References ---------- diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py index f486791318..c8e804ff98 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py @@ -79,6 +79,27 @@ def GET(self): ) server.start() +Configuration +------------- + +Request/Response hooks +********************** + +Utilize request/reponse hooks to execute custom logic to be performed before/after performing a request. Environ is an instance of WSGIEnvironment. +Response_headers is a list of key-value (tuples) representing the response headers returned from the response. + +.. code-block:: python + + def request_hook(span: Span, environ: WSGIEnvironment): + if span and span.is_recording(): + span.set_attribute("custom_user_attribute_from_request_hook", "some-value") + + def response_hook(span: Span, environ: WSGIEnvironment, status: str, response_headers: List): + if span and span.is_recording(): + span.set_attribute("custom_user_attribute_from_response_hook", "some-value") + + OpenTelemetryMiddleware(request_hook=request_hook, response_hook=response_hook) + API --- """