{"id":1048,"library":"opentelemetry-instrumentation-flask","title":"OpenTelemetry Flask Instrumentation","description":"The OpenTelemetry Flask Instrumentation library provides automatic tracing for Flask applications, building upon the OpenTelemetry WSGI middleware to track web requests. It captures Flask-specific features like using URL rule patterns as span names and setting the `http.route` attribute. This package is part of the `opentelemetry-python-contrib` project, which generally maintains a monthly release cadence, and its individual packages are typically in beta status.","status":"active","version":"0.61b0","language":"python","source_language":"en","source_url":"https://github.com/open-telemetry/opentelemetry-python-contrib","tags":["opentelemetry","observability","flask","web","instrumentation","tracing","metrics"],"install":[{"cmd":"pip install opentelemetry-api opentelemetry-sdk opentelemetry-instrumentation-flask opentelemetry-exporter-otlp","lang":"bash","label":"Install core, SDK, Flask instrumentation, and OTLP exporter"}],"dependencies":[{"reason":"The web framework being instrumented.","package":"Flask","optional":false},{"reason":"Core OpenTelemetry API for defining telemetry.","package":"opentelemetry-api","optional":false},{"reason":"Core OpenTelemetry SDK for processing and exporting telemetry data.","package":"opentelemetry-sdk","optional":false}],"imports":[{"symbol":"FlaskInstrumentor","correct":"from opentelemetry.instrumentation.flask import FlaskInstrumentor"}],"quickstart":{"code":"import os\nfrom flask import Flask\nfrom opentelemetry import trace\nfrom opentelemetry.sdk.resources import Resource\nfrom opentelemetry.sdk.trace import TracerProvider\nfrom opentelemetry.sdk.trace.export import BatchSpanProcessor\nfrom opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter\nfrom opentelemetry.instrumentation.flask import FlaskInstrumentor\n\n# Configure OpenTelemetry SDK\n# Ensure these environment variables are set for your OTLP collector\notlp_endpoint = os.environ.get('OTEL_EXPORTER_OTLP_ENDPOINT', 'http://localhost:4318/v1/traces')\nservice_name = os.environ.get('OTEL_SERVICE_NAME', 'my-flask-app')\n\nresource = Resource.create({\n    \"service.name\": service_name,\n    \"service.version\": \"1.0.0\"\n})\n\nprovider = TracerProvider(resource=resource)\nprocessor = BatchSpanProcessor(OTLPSpanExporter(endpoint=otlp_endpoint))\nprovider.add_span_processor(processor)\ntrace.set_tracer_provider(provider)\n\napp = Flask(__name__)\n\n# Instrument the Flask application\nFlaskInstrumentor().instrument_app(app)\n\n@app.route(\"/\")\ndef hello():\n    return \"Hello, World!\"\n\n@app.route(\"/data\")\ndef get_data():\n    # Example of manual span within an instrumented route\n    with trace.get_current_span().tracer.start_as_current_span(\"get-data-logic\"):\n        return {\"value\": 123}\n\nif __name__ == \"__main__\":\n    # IMPORTANT: Do not run with debug=True in production or with auto-instrumentation\n    # due to Flask reloader issues with OpenTelemetry. For development, use\n    # `flask run --no-debugger --no-reloader` or set `debug=False` for basic testing.\n    print(f\"Flask app running on http://127.0.0.1:5000 with OTLP exporter to {otlp_endpoint}\")\n    app.run(host=\"0.0.0.0\", port=5000, debug=False)\n","lang":"python","description":"This quickstart demonstrates how to instrument a basic Flask application using `FlaskInstrumentor`. It sets up a `TracerProvider` with a `BatchSpanProcessor` and `OTLPSpanExporter` to send traces. Run this script, then access `http://localhost:5000/` or `http://localhost:5000/data` to generate traces. Ensure an OpenTelemetry Collector is running and configured to receive OTLP/HTTP traces at the specified endpoint."},"warnings":[{"fix":"Review changelogs carefully when upgrading. Be prepared for potential API changes and adjust your code accordingly.","message":"This instrumentation package is currently in beta (`0.x.x`), indicating that its API and behavior may change in future releases without strictly adhering to semantic versioning until a stable `1.0` release.","severity":"breaking","affected_versions":"All `0.x.x` beta versions"},{"fix":"For development with tracing, run Flask using `flask run --no-debugger --no-reloader` or explicitly set `debug=False` in `app.run()`. In production, use WSGI servers like Gunicorn or uWSGI, which typically don't use the reloader.","message":"Flask's debug mode, which uses a reloader, can conflict with OpenTelemetry's instrumentation process, leading to duplicate spans or no instrumentation. This often occurs when `app.run(debug=True)` is used directly.","severity":"gotcha","affected_versions":"All versions when using Flask's reloader/debug mode."},{"fix":"Ensure `trace.set_tracer_provider(provider)` is called early in your application's lifecycle, and `FlaskInstrumentor().instrument_app(app)` is called after your `app` is initialized and configured but before `app.run()` or a WSGI server takes over.","message":"When manually instrumenting, `FlaskInstrumentor().instrument_app(app)` must be called *after* the Flask application object (`app`) has been created and typically after configuring all blueprints, but *before* the application starts serving requests. Also, the global `TracerProvider` must be set up *before* instrumentation is applied.","severity":"gotcha","affected_versions":"All versions."},{"fix":"Run your Flask application without the reloader when using `opentelemetry-instrument`, e.g., `opentelemetry-instrument flask run --no-debugger --no-reloader`.","message":"When using `opentelemetry-instrument` CLI for auto-instrumentation, Flask's development server with the reloader enabled (`--debug` or `FLASK_DEBUG=1`) is not supported and will lead to broken instrumentation. The CLI relies on patching modules once.","severity":"gotcha","affected_versions":"All versions when using `opentelemetry-instrument` with Flask's reloader."},{"fix":"Upgrade to `opentelemetry-instrumentation-flask` version `0.45b0` or newer to align with updated semantic conventions. Be aware of potential changes in how your observability backend groups or displays traces if you were relying on the older span naming.","message":"Older versions of Flask instrumentation (`<0.45b0`) did not include the HTTP method in the span name. This was changed to `HTTP {method} {route}` for better semantic convention compliance.","severity":"deprecated","affected_versions":"<0.45b0"},{"fix":"Ensure that `flask` is installed in your environment, typically via `pip install flask`.","message":"The `flask` package, which is a required dependency, is not installed. This prevents `opentelemetry-instrumentation-flask` from being used as it cannot find the Flask application to instrument.","severity":"breaking","affected_versions":"All versions."},{"fix":"Ensure `flask` is included in your project's dependencies and installed (e.g., `pip install flask`).","message":"The `opentelemetry-instrumentation-flask` library requires the `flask` package to be installed in your environment. Failure to install Flask will result in a `ModuleNotFoundError` when attempting to import Flask components.","severity":"gotcha","affected_versions":"All versions."}],"env_vars":null,"last_verified":"2026-05-12T23:08:02.152Z","next_check":"2026-06-29T00:00:00.000Z","problems":[{"fix":"Install the package using pip: `pip install opentelemetry-instrumentation-flask`","cause":"This error occurs when the `opentelemetry-instrumentation-flask` package is not installed in your Python environment or is not accessible.","error":"ModuleNotFoundError: No module named 'opentelemetry.instrumentation.flask'"},{"fix":"Disable the Flask reloader during development by setting `debug=True, use_reloader=False` in `app.run()`, or guard OpenTelemetry initialization with `if os.environ.get(\"WERKZEUG_RUN_MAIN\") == \"true\":`.","cause":"Flask's debug mode reloader spawns a child process which can lead to OpenTelemetry being initialized twice or not at all in the child process, resulting in duplicate or missing traces/spans.","error":"Flask debug mode reloader breaks instrumentation"},{"fix":"Ensure compatible versions of Flask and Werkzeug are installed, typically by pinning Flask to a version below 3.0.0 if the instrumentation package has not yet officially added support for Flask 3.0.0 and its `Werkzeug` dependency. Check the `opentelemetry-instrumentation-flask` documentation for supported versions.","cause":"This problem arises from version incompatibility where `opentelemetry-instrumentation-flask` (especially older versions) might expect `Werkzeug<3.0.0` while a newer Flask version pulls in `Werkzeug==3.0.0`, causing the instrumentation to silently fail or not load.","error":"opentelemetry-instrument fails to load flask instrumentation if werkzeug==3.0.0"},{"fix":"Verify that the OpenTelemetry SDK, tracer provider, and exporters are properly initialized before your application code runs. Double-check all relevant environment variables for correct values and ensure network connectivity to your observability backend. Add a `ConsoleSpanExporter` during debugging to confirm spans are being generated locally.","cause":"Traces might not appear due to incorrect OpenTelemetry SDK initialization, missing or misconfigured environment variables (e.g., `OTEL_EXPORTER_OTLP_ENDPOINT`, `OTEL_SERVICE_NAME`), or network connectivity issues preventing the exporter from reaching the telemetry backend.","error":"application not sending any traces"}],"ecosystem":"pypi","meta_description":null,"install_score":0,"install_tag":"stale","quickstart_score":null,"quickstart_tag":null,"pypi_latest":"0.62b1","cli_name":"","install_checks":{"last_tested":"2026-05-12","tag":"stale","tag_description":"widespread failures or data too old to trust","installed_version":"0.62b1","pypi_latest":"0.62b1","is_stale":false,"results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"opentelemetry-api","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"broken","install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":"52.2M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"opentelemetry-api","exit_code":1,"wheel_type":null,"failure_reason":null,"import_side_effects":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":"opentelemetry-api","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"broken","install_time_s":5.7,"import_time_s":null,"mem_mb":null,"disk_size":"50M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"opentelemetry-api","exit_code":1,"wheel_type":null,"failure_reason":null,"import_side_effects":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":"opentelemetry-api","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"broken","install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":"55.7M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"opentelemetry-api","exit_code":1,"wheel_type":null,"failure_reason":null,"import_side_effects":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":"opentelemetry-api","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"broken","install_time_s":4.9,"import_time_s":null,"mem_mb":null,"disk_size":"54M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"opentelemetry-api","exit_code":1,"wheel_type":null,"failure_reason":null,"import_side_effects":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":"opentelemetry-api","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"broken","install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":"47.3M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"opentelemetry-api","exit_code":1,"wheel_type":null,"failure_reason":null,"import_side_effects":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":"opentelemetry-api","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"broken","install_time_s":4,"import_time_s":null,"mem_mb":null,"disk_size":"45M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"opentelemetry-api","exit_code":1,"wheel_type":null,"failure_reason":null,"import_side_effects":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":"opentelemetry-api","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"broken","install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":"47.0M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"opentelemetry-api","exit_code":1,"wheel_type":null,"failure_reason":null,"import_side_effects":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":"opentelemetry-api","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"broken","install_time_s":4,"import_time_s":null,"mem_mb":null,"disk_size":"45M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"opentelemetry-api","exit_code":1,"wheel_type":null,"failure_reason":null,"import_side_effects":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":"opentelemetry-api","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"broken","install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":"51.4M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"opentelemetry-api","exit_code":1,"wheel_type":null,"failure_reason":null,"import_side_effects":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":"opentelemetry-api","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"broken","install_time_s":6.4,"import_time_s":null,"mem_mb":null,"disk_size":"49M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"opentelemetry-api","exit_code":1,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null}]},"quickstart_checks":{"last_tested":"2026-04-24","tag":null,"tag_description":null,"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}]}}