{"id":2167,"library":"opentelemetry-instrumentation-starlette","title":"OpenTelemetry Starlette Instrumentation","description":"This library provides automatic and manual instrumentation for the Starlette web framework, enabling the collection of telemetry data like traces and metrics for HTTP requests. It's an active component of the OpenTelemetry Python Contrib project, currently in a beta release phase, indicating ongoing development and potential for API evolution.","status":"active","version":"0.62b0","language":"en","source_language":"en","source_url":"https://github.com/open-telemetry/opentelemetry-python-contrib","tags":["opentelemetry","starlette","observability","tracing","apm","asgi"],"install":[{"cmd":"pip install opentelemetry-instrumentation-starlette opentelemetry-sdk opentelemetry-exporter-otlp uvicorn starlette","lang":"bash","label":"Install with basic OTLP exporter and ASGI server"}],"dependencies":[{"reason":"Core web framework being instrumented.","package":"starlette"},{"reason":"OpenTelemetry API for Python.","package":"opentelemetry-api"},{"reason":"OpenTelemetry SDK for Python.","package":"opentelemetry-sdk"},{"reason":"Base OpenTelemetry instrumentation utilities.","package":"opentelemetry-instrumentation"},{"reason":"Standardized semantic conventions for telemetry.","package":"opentelemetry-semantic-conventions"},{"reason":"HTTP utilities for instrumentation.","package":"opentelemetry-util-http"},{"reason":"ASGI (Asynchronous Server Gateway Interface) utilities, a core dependency for Starlette.","package":"asgiref"}],"imports":[{"symbol":"StarletteInstrumentor","correct":"from opentelemetry.instrumentation.starlette import StarletteInstrumentor"}],"quickstart":{"code":"import os\nfrom opentelemetry import trace\nfrom opentelemetry.sdk.resources import Resource, SERVICE_NAME\nfrom opentelemetry.sdk.trace import TracerProvider\nfrom opentelemetry.sdk.trace.export import BatchSpanProcessor\nfrom opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter\nfrom opentelemetry.instrumentation.starlette import StarletteInstrumentor\nfrom starlette.applications import Starlette\nfrom starlette.responses import PlainTextResponse\nfrom starlette.routing import Route\n\n# Configure OpenTelemetry SDK\nresource = Resource.create({\n    SERVICE_NAME: os.environ.get('OTEL_SERVICE_NAME', 'starlette-app')\n})\n\ntracer_provider = TracerProvider(resource=resource)\n\notlp_exporter = OTLPSpanExporter(\n    endpoint=os.environ.get('OTEL_EXPORTER_OTLP_ENDPOINT', 'localhost:4317'),\n    insecure=True # Use secure=False for production with TLS\n)\nspan_processor = BatchSpanProcessor(otlp_exporter)\ntracer_provider.add_span_processor(span_processor)\ntrace.set_tracer_provider(tracer_provider)\n\n\n# Define Starlette application\nasync def homepage(request):\n    with trace.get_current_span() as span:\n        span.set_attribute(\"custom_attribute\", \"hello from homepage\")\n    return PlainTextResponse(\"Hello, world!\")\n\nasync def user_detail(request):\n    user_id = request.path_params['user_id']\n    return PlainTextResponse(f\"User ID: {user_id}\")\n\nroutes = [\n    Route(\"/\", homepage),\n    Route(\"/users/{user_id:int}\", user_detail),\n]\n\napp = Starlette(routes=routes)\n\n# Instrument the Starlette application\nStarletteInstrumentor().instrument_app(app)\n\n# To run: uvicorn your_app_file_name:app --port 8000\n# Make sure an OTLP collector is running at localhost:4317 (or specified endpoint)\n","lang":"python","description":"This quickstart demonstrates how to instrument a Starlette application with OpenTelemetry for tracing. It sets up a basic `TracerProvider` with an OTLP gRPC exporter and then applies the `StarletteInstrumentor` to the application. It's configured to use environment variables for service name and OTLP endpoint for flexibility."},"warnings":[{"fix":"Review release notes for each new version. Pin exact versions for stability in production environments.","message":"The library `opentelemetry-instrumentation-starlette` is currently in beta (`0.62b0`). This means the API is subject to change without adhering to strict semantic versioning, and stability guarantees are limited. Production usage should monitor release notes for breaking changes.","severity":"gotcha","affected_versions":"All versions with 'b' suffix (e.g., 0.x.ybZ)"},{"fix":"Ensure OpenTelemetry SDK setup code runs at the earliest possible point in your application's lifecycle, typically at the top of your main application file or in a dedicated setup module that is imported first. For auto-instrumentation via `opentelemetry-instrument`, ensure the command is used correctly.","message":"The OpenTelemetry SDK (including `TracerProvider` and exporters) *must* be initialized and configured before any instrumented library (like Starlette) is imported or used. Failing to do so can result in instrumentation hooks not being applied, leading to no telemetry data being collected.","severity":"breaking","affected_versions":"All versions"},{"fix":"Consider using `uvicorn` with a single worker, or `gunicorn` with `uvicorn.workers.UvicornWorker` and `OTEL_PYTHON_AUTO_INSTRUMENTATION_ENABLE_FORK_PATCH=true` (if available and tested) or use programmatic instrumentation to explicitly initialize the SDK in each worker process after forking. Consult OpenTelemetry Python documentation on pre-fork server issues.","message":"When running Starlette applications with pre-forking ASGI servers like Gunicorn (especially with multiple workers), OpenTelemetry's automatic metrics generation may be unreliable or broken. This is due to Python's forking model and how background threads (e.g., in `PeriodicExportingMetricReader`) interact with child processes.","severity":"gotcha","affected_versions":"All versions with multi-worker Gunicorn configurations"},{"fix":"Generally, place `StarletteInstrumentor().instrument_app(app)` early in your application's setup, often directly after the `Starlette` app instance is created. If using manual middleware, ensure `OpenTelemetryMiddleware` (from `opentelemetry-instrumentation-asgi`) is positioned appropriately in your middleware stack.","message":"The order of OpenTelemetry instrumentation relative to other Starlette middleware can be crucial. If other middleware modifies the ASGI scope in a way that interferes with the instrumentation, or if instrumentation needs to capture attributes set by other middleware, placement matters.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure you are using `opentelemetry-instrumentation-starlette` version `0.55b0` or newer to benefit from fixes related to Starlette version compatibility and header capture.","message":"Older versions of `opentelemetry-instrumentation-starlette` (prior to `1.34.0/0.55b0`) had known issues with capturing custom headers correctly, particularly with Starlette versions >= 0.15.0. While fixed in newer versions, using outdated instrumentation might lead to missing header attributes.","severity":"deprecated","affected_versions":"< 0.55b0 (OpenTelemetry Python Contrib version nomenclature)"},{"fix":"Use environment variables `OTEL_PYTHON_STARLETTE_EXCLUDED_URLS` (Starlette-specific) or `OTEL_PYTHON_EXCLUDED_URLS` (global) with comma-delimited regex patterns to exclude URLs. Similarly, use `OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS` to sanitize header values.","message":"To prevent storing sensitive data or to reduce noise, certain URLs or HTTP headers should be excluded from tracing. If not configured, sensitive paths (e.g., health checks, client secrets) might generate unnecessary spans or expose data.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-09T00:00:00.000Z","next_check":"2026-07-08T00:00:00.000Z"}