ASGI Instrumentation for OpenTelemetry
raw JSON → 0.61b0 verified Tue May 12 auth: no python install: verified quickstart: stale
This library provides ASGI middleware to automatically instrument ASGI applications (such as FastAPI, Starlette, Django-channels, or Quart) for OpenTelemetry. It enables tracing and metrics collection for HTTP requests, tracking request timing and attributes. The library is currently in beta (v0.61b0) and is part of the `opentelemetry-python-contrib` repository, with new versions typically released on a monthly cadence.
pip install opentelemetry-instrumentation-asgi opentelemetry-sdk Common errors
error ModuleNotFoundError: No module named 'opentelemetry.instrumentation.asgi' ↓
cause The `opentelemetry-instrumentation-asgi` package has not been installed in the Python environment where your ASGI application is running, or the environment is not correctly activated.
fix
Ensure the package is installed using pip:
pip install opentelemetry-instrumentation-asgi error Django ASGI OpenTelemetry instrumentation not working ↓
cause The default OpenTelemetry Django instrumentation often targets WSGI applications. For ASGI applications (such as those using Django Channels), `opentelemetry-instrumentation-asgi` must be explicitly installed and applied as ASGI middleware to capture traces.
fix
Install
opentelemetry-instrumentation-asgi and modify your asgi.py to wrap your application with OpenTelemetryMiddleware:
import os
from django.core.asgi import get_asgi_application
from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'your_project.settings')
application = get_asgi_application()
application = OpenTelemetryMiddleware(application) error AttributeError: 'ASGIRequest' object has no attribute 'environ' ↓
cause This error occurs when attempting to access WSGI-specific request attributes (like `environ`) on an ASGI request object, which uses a different `scope` structure for request details. This often happens when mixing WSGI-oriented utility functions with an ASGI application.
fix
Instead of
request.environ, access ASGI scope attributes directly through request.scope or use ASGI-compatible utility functions provided by opentelemetry.instrumentation.asgi for extracting attributes. error opentelemetry-instrumentation-asgi http.url incorrect root_path ↓
cause Older versions of `opentelemetry-instrumentation-asgi` had a bug where the `http.url` attribute in generated spans did not correctly account for the `root_path` specified in the ASGI scope, leading to inaccurate URLs in traces.
fix
Upgrade
opentelemetry-instrumentation-asgi to a newer version (e.g., 0.46b0 or later, as the issue was fixed after version 0.45b0). Run: pip install --upgrade opentelemetry-instrumentation-asgi Warnings
gotcha The `opentelemetry-instrumentation-asgi` package is currently in beta. While actively developed, its API and behavior may change before a stable `1.0` release. It is not generally recommended for production environments where stability is critical. ↓
fix Be aware of potential breaking changes in minor updates. For production, consider using stable, manually instrumented components or a more mature OpenTelemetry language agent.
breaking Starting with version `0.61b0`, `SpanAttributes` were replaced with semantic convention constants. Directly referencing `SpanAttributes` might lead to `AttributeError` or incorrect attribute names. ↓
fix Update your code to use constants from `opentelemetry.semconv.trace` or similar `semconv` modules, or rely on automatic instrumentation to apply correct semantic conventions.
gotcha When using pre-fork servers like Gunicorn with multiple workers, OpenTelemetry's automatic metric generation might break. This is due to how child processes handle background threads and locks. Tracing usually remains functional, and Uvicorn with multiple workers is supported for both traces and metrics. ↓
fix For Gunicorn, consider running with a single worker (`--workers 1`), or use programmatic auto-instrumentation. If using Uvicorn with multiple workers, ensure your setup is compatible with OpenTelemetry's recommendations.
gotcha To capture HTTP request and response headers as span attributes, specific environment variables must be set (e.g., `OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST`, `OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE`). Headers are case-insensitive. ↓
fix Set environment variables like `OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST='Content-Type,X-Request-ID'` or `'.*'` to capture all headers (use with caution). The attribute names will be `http.request.header.<header_name>`.
gotcha The `opentelemetry-instrumentation-asgi` package does not provide a `fastapi` extra. FastAPI instrumentation is typically provided by a separate package, `opentelemetry-instrumentation-fastapi`. Attempting to install `opentelemetry-instrumentation-asgi[fastapi]` will result in a warning. ↓
fix If FastAPI instrumentation is needed, install `opentelemetry-instrumentation-fastapi` as a separate package. Avoid using `[fastapi]` when installing `opentelemetry-instrumentation-asgi`.
gotcha The `opentelemetry-instrumentation-asgi` package does not officially provide a `fastapi` extra. Attempting to install it with `[fastapi]` will result in a warning indicating that the extra is not found and will only install the base package dependencies. ↓
fix Avoid using the `[fastapi]` extra. If FastAPI-specific instrumentation is required, check the OpenTelemetry documentation for alternative, dedicated FastAPI instrumentation packages or rely on the base ASGI instrumentation.
Install
pip install 'opentelemetry-instrumentation-asgi[fastapi]' # For FastAPI specific dependencies Install compatibility verified last tested: 2026-05-12
python os / libc variant status wheel install import disk
3.10 alpine (musl) fastapi - - - -
3.10 alpine (musl) opentelemetry-instrumentation-asgi wheel - 0.28s 24.4M
3.10 alpine (musl) fastapi - - - -
3.10 alpine (musl) opentelemetry-instrumentation-asgi - - 0.31s 24.2M
3.10 slim (glibc) fastapi - - - -
3.10 slim (glibc) opentelemetry-instrumentation-asgi wheel 3.0s 0.20s 25M
3.10 slim (glibc) fastapi - - - -
3.10 slim (glibc) opentelemetry-instrumentation-asgi - - 0.20s 25M
3.11 alpine (musl) fastapi - - - -
3.11 alpine (musl) opentelemetry-instrumentation-asgi wheel - 0.41s 27.0M
3.11 alpine (musl) fastapi - - - -
3.11 alpine (musl) opentelemetry-instrumentation-asgi - - 0.47s 26.7M
3.11 slim (glibc) fastapi - - - -
3.11 slim (glibc) opentelemetry-instrumentation-asgi wheel 3.0s 0.36s 28M
3.11 slim (glibc) fastapi - - - -
3.11 slim (glibc) opentelemetry-instrumentation-asgi - - 0.57s 27M
3.12 alpine (musl) fastapi - - - -
3.12 alpine (musl) opentelemetry-instrumentation-asgi wheel - 0.60s 18.7M
3.12 alpine (musl) fastapi - - - -
3.12 alpine (musl) opentelemetry-instrumentation-asgi - - 0.62s 18.5M
3.12 slim (glibc) fastapi - - - -
3.12 slim (glibc) opentelemetry-instrumentation-asgi wheel 2.6s 0.54s 19M
3.12 slim (glibc) fastapi - - - -
3.12 slim (glibc) opentelemetry-instrumentation-asgi - - 0.59s 19M
3.13 alpine (musl) fastapi - - - -
3.13 alpine (musl) opentelemetry-instrumentation-asgi wheel - 0.54s 18.4M
3.13 alpine (musl) fastapi - - - -
3.13 alpine (musl) opentelemetry-instrumentation-asgi - - 0.58s 18.1M
3.13 slim (glibc) fastapi - - - -
3.13 slim (glibc) opentelemetry-instrumentation-asgi wheel 2.4s 0.55s 19M
3.13 slim (glibc) fastapi - - - -
3.13 slim (glibc) opentelemetry-instrumentation-asgi - - 0.54s 19M
3.9 alpine (musl) fastapi - - - -
3.9 alpine (musl) opentelemetry-instrumentation-asgi wheel - 0.24s 23.9M
3.9 alpine (musl) fastapi - - - -
3.9 alpine (musl) opentelemetry-instrumentation-asgi - - 0.25s 23.7M
3.9 slim (glibc) fastapi - - - -
3.9 slim (glibc) opentelemetry-instrumentation-asgi wheel 3.4s 0.24s 24M
3.9 slim (glibc) fastapi - - - -
3.9 slim (glibc) opentelemetry-instrumentation-asgi - - 0.21s 24M
Imports
- OpenTelemetryMiddleware
from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware
Quickstart stale last tested: 2026-04-24
import os
import uvicorn
from opentelemetry import trace
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor
from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware
# Configure OpenTelemetry SDK
resource = Resource.create({"service.name": "my-asgi-app"})
provider = TracerProvider(resource=resource)
processor = SimpleSpanProcessor(ConsoleSpanExporter())
provider.add_span_processor(processor)
trace.set_tracer_provider(provider)
# Define a simple ASGI application
async def hello_world_app(scope, receive, send):
assert scope['type'] == 'http'
await send({
'type': 'http.response.start',
'status': 200,
'headers': [
(b'content-type', b'text/plain'),
],
})
await send({
'type': 'http.response.body',
'body': b'Hello, OpenTelemetry World!'
})
# Instrument the ASGI application
instrumented_app = OpenTelemetryMiddleware(hello_world_app)
# To run this example:
# 1. Save as 'app.py'
# 2. Run: uvicorn app:instrumented_app --port 8000
# 3. Access http://localhost:8000/ in your browser.
# You will see trace output in the console where uvicorn is running.
# Note: This is an embedded example. In a real application, you would typically
# apply the middleware to your framework's app instance (e.g., FastAPI, Starlette).
# For example, for FastAPI:
# from fastapi import FastAPI
# app = FastAPI()
# app.add_middleware(OpenTelemetryMiddleware)