{"id":790,"library":"opentelemetry-instrumentation-asgi","title":"ASGI Instrumentation for OpenTelemetry","description":"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.","status":"active","version":"0.61b0","language":"python","source_language":"en","source_url":"https://github.com/open-telemetry/opentelemetry-python-contrib","tags":["opentelemetry","observability","tracing","metrics","asgi","fastapi","starlette","quart","django-channels"],"install":[{"cmd":"pip install opentelemetry-instrumentation-asgi opentelemetry-sdk","lang":"bash","label":"Install package and SDK"},{"cmd":"pip install 'opentelemetry-instrumentation-asgi[fastapi]' # For FastAPI specific dependencies","lang":"bash","label":"Install with FastAPI extras (example)"}],"dependencies":[{"reason":"Core OpenTelemetry API, fundamental for all instrumentation.","package":"opentelemetry-api","optional":false},{"reason":"OpenTelemetry SDK for processing and exporting telemetry data (required for a functional setup).","package":"opentelemetry-sdk","optional":false},{"reason":"Base classes and utilities for OpenTelemetry instrumentation.","package":"opentelemetry-instrumentation","optional":false},{"reason":"Defines standard attribute names for OpenTelemetry telemetry.","package":"opentelemetry-semantic-conventions","optional":false},{"reason":"Shared utilities for HTTP-related instrumentations.","package":"opentelemetry-util-http","optional":false},{"reason":"Requires an ASGI framework like FastAPI, Starlette, Quart, or Django-channels to function, but these are application dependencies, not direct Python package dependencies.","package":"asgi-compatible-framework","optional":true}],"imports":[{"symbol":"OpenTelemetryMiddleware","correct":"from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware"}],"quickstart":{"code":"import os\nimport uvicorn\nfrom opentelemetry import trace\nfrom opentelemetry.sdk.resources import Resource\nfrom opentelemetry.sdk.trace import TracerProvider\nfrom opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor\nfrom opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware\n\n# Configure OpenTelemetry SDK\nresource = Resource.create({\"service.name\": \"my-asgi-app\"})\nprovider = TracerProvider(resource=resource)\nprocessor = SimpleSpanProcessor(ConsoleSpanExporter())\nprovider.add_span_processor(processor)\ntrace.set_tracer_provider(provider)\n\n# Define a simple ASGI application\nasync def hello_world_app(scope, receive, send):\n    assert scope['type'] == 'http'\n    await send({\n        'type': 'http.response.start',\n        'status': 200,\n        'headers': [\n            (b'content-type', b'text/plain'),\n        ],\n    })\n    await send({\n        'type': 'http.response.body',\n        'body': b'Hello, OpenTelemetry World!'\n    })\n\n# Instrument the ASGI application\ninstrumented_app = OpenTelemetryMiddleware(hello_world_app)\n\n# To run this example:\n# 1. Save as 'app.py'\n# 2. Run: uvicorn app:instrumented_app --port 8000\n# 3. Access http://localhost:8000/ in your browser.\n# You will see trace output in the console where uvicorn is running.\n\n# Note: This is an embedded example. In a real application, you would typically\n# apply the middleware to your framework's app instance (e.g., FastAPI, Starlette).\n# For example, for FastAPI:\n# from fastapi import FastAPI\n# app = FastAPI()\n# app.add_middleware(OpenTelemetryMiddleware)","lang":"python","description":"This quickstart demonstrates how to instrument a basic ASGI application using `OpenTelemetryMiddleware`. It configures a simple OpenTelemetry SDK with a console exporter to print traces directly to the terminal. After running the `uvicorn` command, accessing the application will generate and display trace information."},"warnings":[{"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.","message":"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.","severity":"gotcha","affected_versions":"All beta versions (e.g., <1.0.0)"},{"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.","message":"Starting with version `0.61b0`, `SpanAttributes` were replaced with semantic convention constants. Directly referencing `SpanAttributes` might lead to `AttributeError` or incorrect attribute names.","severity":"breaking","affected_versions":">=0.61b0"},{"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.","message":"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.","severity":"gotcha","affected_versions":"All versions"},{"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>`.","message":"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.","severity":"gotcha","affected_versions":"All versions"},{"fix":"If FastAPI instrumentation is needed, install `opentelemetry-instrumentation-fastapi` as a separate package. Avoid using `[fastapi]` when installing `opentelemetry-instrumentation-asgi`.","message":"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.","severity":"gotcha","affected_versions":"All versions of `opentelemetry-instrumentation-asgi` that do not explicitly declare a `fastapi` extra (which appears to be current behavior)."},{"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.","message":"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.","severity":"gotcha","affected_versions":"0.62b0 and potentially other versions where `fastapi` extra is not explicitly defined."}],"env_vars":null,"last_verified":"2026-05-12T19:10:45.086Z","next_check":"2026-06-27T00:00:00.000Z","problems":[{"fix":"Ensure the package is installed using pip: `pip install 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.","error":"ModuleNotFoundError: No module named 'opentelemetry.instrumentation.asgi'"},{"fix":"Install `opentelemetry-instrumentation-asgi` and modify your `asgi.py` to wrap your application with `OpenTelemetryMiddleware`:\n```python\nimport os\nfrom django.core.asgi import get_asgi_application\nfrom opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware\n\nos.environ.setdefault('DJANGO_SETTINGS_MODULE', 'your_project.settings')\n\napplication = get_asgi_application()\napplication = OpenTelemetryMiddleware(application)\n```","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.","error":"Django ASGI OpenTelemetry instrumentation not working"},{"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.","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.","error":"AttributeError: 'ASGIRequest' object has no attribute 'environ'"},{"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`","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.","error":"opentelemetry-instrumentation-asgi http.url incorrect root_path"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":0,"quickstart_tag":"stale","pypi_latest":"0.62b1","cli_name":"opentelemetry-instrumentation","install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"fastapi","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.28,"mem_mb":8.9,"disk_size":"24.4M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"fastapi","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.31,"mem_mb":8.9,"disk_size":"24.2M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"fastapi","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":3,"import_time_s":0.2,"mem_mb":8.9,"disk_size":"25M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"fastapi","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.2,"mem_mb":8.9,"disk_size":"25M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"fastapi","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.41,"mem_mb":10.2,"disk_size":"27.0M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"fastapi","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.47,"mem_mb":10.2,"disk_size":"26.7M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"fastapi","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":3,"import_time_s":0.36,"mem_mb":10.2,"disk_size":"28M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"fastapi","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.57,"mem_mb":10.2,"disk_size":"27M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"fastapi","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.6,"mem_mb":10.2,"disk_size":"18.7M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"fastapi","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.62,"mem_mb":10.2,"disk_size":"18.5M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"fastapi","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":2.6,"import_time_s":0.54,"mem_mb":10.2,"disk_size":"19M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"fastapi","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.59,"mem_mb":10.2,"disk_size":"19M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"fastapi","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.54,"mem_mb":9.9,"disk_size":"18.4M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"fastapi","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.58,"mem_mb":9.9,"disk_size":"18.1M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"fastapi","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":2.4,"import_time_s":0.55,"mem_mb":9.9,"disk_size":"19M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"fastapi","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.54,"mem_mb":9.9,"disk_size":"19M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"fastapi","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.24,"mem_mb":8.1,"disk_size":"23.9M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"fastapi","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.25,"mem_mb":8.1,"disk_size":"23.7M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"fastapi","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":3.4,"import_time_s":0.24,"mem_mb":8.1,"disk_size":"24M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"fastapi","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.21,"mem_mb":8.1,"disk_size":"24M"}]},"quickstart_checks":{"last_tested":"2026-04-24","tag":"stale","tag_description":"widespread failures or data too old to trust","results":[{"runtime":"python:3.10-alpine","exit_code":1},{"runtime":"python:3.10-slim","exit_code":1},{"runtime":"python:3.11-alpine","exit_code":1},{"runtime":"python:3.11-slim","exit_code":1},{"runtime":"python:3.12-alpine","exit_code":1},{"runtime":"python:3.12-slim","exit_code":1},{"runtime":"python:3.13-alpine","exit_code":1},{"runtime":"python:3.13-slim","exit_code":1},{"runtime":"python:3.9-alpine","exit_code":1},{"runtime":"python:3.9-slim","exit_code":1}]}}