{"id":194,"library":"ddtrace","title":"Datadog Python APM Tracer (ddtrace)","description":"Datadog APM Python tracing library. Current version: 4.6.4 (Mar 2026). Three breaking major versions since 2023: v2 (dropped Python 2.7/3.5/3.6, removed DD_CALL_BASIC_CONFIG), v3 (dropped Python 3.7, removed deprecated config names), v4 (dropped Python 3.8, removed Pin class, removed Span.set_tag_str, removed ddtrace.settings package). Preferred usage is ddtrace-run CLI wrapper — NOT importing patch_all() in code. Requires Datadog Agent running separately. Auto-instrumentation patches libraries at import time.","status":"active","version":"4.6.4","language":"python","source_language":"en","source_url":"https://github.com/DataDog/dd-trace-py","tags":["datadog","ddtrace","apm","tracing","observability","python","monitoring"],"install":[{"cmd":"pip install ddtrace","lang":"bash","label":"Python"}],"dependencies":[{"reason":"Required separately. ddtrace sends traces to a local Agent process. Install from datadoghq.com/agent.","package":"Datadog Agent","optional":false}],"imports":[{"note":"patch_all() and patch() must be called BEFORE the library being patched is imported. ddtrace-run handles this automatically. In code, call patch() at the very top of the entry point before any other imports.","wrong":"# Wrong: patch_all() called after imports — too late to instrument\nimport flask\nimport sqlalchemy\nfrom ddtrace import patch_all\npatch_all()  # flask and sqlalchemy already imported — not patched\n\n# Wrong: calling patch() inside app factory — same issue\ndef create_app():\n    from ddtrace import patch\n    patch(flask=True)  # flask already imported above","symbol":"ddtrace-run (preferred — auto-instrumentation)","correct":"# Preferred: use ddtrace-run CLI wrapper\n# This patches libraries at startup before your code imports them\n\n# Set env vars:\n# DD_SERVICE=my-service\n# DD_ENV=production\n# DD_VERSION=1.0.0\n# DD_AGENT_HOST=localhost  (default)\n# DD_TRACE_AGENT_PORT=8126  (default)\n\n# Run your app:\n# ddtrace-run python app.py\n# ddtrace-run gunicorn app:application\n# ddtrace-run uvicorn app:app\n\n# Verify config:\n# ddtrace-run --info"},{"note":"Pin class removed in v4. set_tag_str() removed in v4 — use set_tag() for all tag types. ddtrace.settings package removed in v4 — use environment variables instead.","wrong":"# Wrong in v4: Pin class removed\nfrom ddtrace import Pin\nPin.override(my_client, service='my-svc')  # ImportError in v4\n\n# Wrong in v4: set_tag_str removed\nspan.set_tag_str('key', 'value')  # AttributeError in v4 — use set_tag()","symbol":"Manual tracing (custom spans)","correct":"from ddtrace import tracer\n\n# Custom span\nwith tracer.trace('my.operation', service='my-service', resource='checkout') as span:\n    span.set_tag('user.id', '123')\n    span.set_tag('order.id', 'ord-456')\n    # do work\n\n# Decorator\nfrom ddtrace import tracer\n\n@tracer.wrap(service='my-service', resource='process_payment')\ndef process_payment(order_id):\n    pass\n\n# Error tracking\ntry:\n    risky_operation()\nexcept Exception as e:\n    span.error = 1\n    span.set_tag('error.msg', str(e))\n    raise"}],"quickstart":{"code":"# pip install ddtrace\n# Requires Datadog Agent running at localhost:8126\n\n# Option 1: ddtrace-run (recommended)\n# DD_SERVICE=my-app DD_ENV=prod ddtrace-run python app.py\n\n# Option 2: manual patch at top of entry point (before all other imports)\nfrom ddtrace import patch\npatch(all=True)  # must be before any library imports\n\n# OR selectively:\n# patch(requests=True, sqlalchemy=True, redis=True)\n\nimport flask  # patched because patch() was called first\n\nfrom ddtrace import tracer\n\napp = flask.Flask(__name__)\n\n@app.route('/checkout')\ndef checkout():\n    with tracer.trace('checkout.process', resource='checkout') as span:\n        span.set_tag('user.id', flask.request.args.get('user_id'))\n        # Unified Service Tagging via env vars:\n        # DD_SERVICE, DD_ENV, DD_VERSION\n        return 'ok'\n\n# Check agent connectivity:\n# ddtrace-run --info","lang":"python","description":"ddtrace — auto-instrumentation via ddtrace-run and custom spans."},"warnings":[{"fix":"v4 requires Python 3.9+. v3 requires Python 3.8+. v2 requires Python 3.7+.","message":"v4.0.0 dropped Python 3.8. v3.0.0 dropped Python 3.7. v2.0.0 dropped Python 2.7/3.5/3.6. Check Python version before upgrading major versions.","severity":"breaking","affected_versions":"all"},{"fix":"Remove Pin usage. Configure integrations via environment variables or ddtrace.config instead.","message":"Pin class removed in v4.0. Code using Pin.get_from(), Pin.override(), ddtrace.Pin raises ImportError.","severity":"breaking","affected_versions":">= 4.0"},{"fix":"Use span.set_tag('key', 'value') for all tag types.","message":"Span.set_tag_str() removed in v4.0. Raises AttributeError.","severity":"breaking","affected_versions":">= 4.0"},{"fix":"Use environment variables (DD_TRACE_*, DD_SERVICE, etc.) for configuration.","message":"ddtrace.settings package removed in v4.0. Code importing from ddtrace.settings raises ImportError.","severity":"breaking","affected_versions":">= 4.0"},{"fix":"Use ddtrace-run CLI wrapper which handles import order automatically.","message":"patch_all() and patch() must be called BEFORE the library being instrumented is imported. Calling after import silently produces no instrumentation.","severity":"breaking","affected_versions":"all"},{"fix":"Remove DD_CALL_BASIC_CONFIG from environment. ddtrace now logs to stdout by default.","message":"DD_CALL_BASIC_CONFIG removed in v2.0. Raises error if set.","severity":"breaking","affected_versions":">= 2.0"},{"fix":"Run Datadog Agent before starting app. Verify with: ddtrace-run --info. Override with DD_AGENT_HOST and DD_TRACE_AGENT_PORT.","message":"Datadog Agent must be running at localhost:8126 (default). Without it, traces are silently dropped — no error raised.","severity":"gotcha","affected_versions":"all"},{"fix":"Set DD_SERVICE=my-service DD_ENV=production DD_VERSION=1.0.0 before running.","message":"Unified Service Tagging requires DD_SERVICE, DD_ENV, DD_VERSION env vars. Without them, services appear as unnamed in Datadog UI.","severity":"gotcha","affected_versions":"all"},{"fix":"Use `ddtrace.patch_all()` to instrument all available integrations, or specify individual integrations using `ddtrace.patch(integration_name=True, ...)`.","message":"Calling `ddtrace.patch(all=True)` is incorrect and will raise `ddtrace._monkey.ModuleNotFoundException`. The `patch` function expects specific integration names as keyword arguments (e.g., `patch(flask=True)`).","severity":"breaking","affected_versions":"all"},{"fix":"Use ddtrace.patch_all() to instrument all available integrations, or ddtrace.patch('integration_name') for specific ones.","message":"Calling ddtrace.patch(all=True) is incorrect and will raise a ModuleNotFoundException. 'all' is not a valid module name for selective patching.","severity":"breaking","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-05-12T09:57:19.242Z","next_check":"2026-06-25T00:00:00.000Z","problems":[{"fix":"Ensure the Datadog Agent is running and accessible from the application host. Verify `DD_TRACE_AGENT_URL` (or `DD_AGENT_HOST` and `DD_AGENT_PORT`) environment variables are correctly set to the Agent's address. Use `ddtrace-run --info` to check the tracer's connection to the agent.","cause":"The `ddtrace` library cannot connect to the Datadog Agent, usually because the Agent is not running, is on a different host/port than configured, or its connection limit has been reached.","error":"Failed to send traces to Datadog Agent...: ConnectionRefusedError(111, 'Connection refused')"},{"fix":"Upgrade your `pip` version to 18 or newer using `pip install -U pip>=18`.","cause":"This error occurs during `ddtrace` installation, indicating that `pip` is having trouble building the `ddtrace` package due to a missing `Cython` module or an outdated `pip` version.","error":"ModuleNotFoundError: No module named 'Cython'"},{"fix":"Migrate your configuration to use environment variables or direct integration configurations instead of `Pin.app`. For instance, configure service names and other tracing metadata via `DD_SERVICE` or integration-specific environment variables.","cause":"The `Pin.app` attribute, along with `Pin.app_type`, was removed in `ddtrace` v4.x as part of API simplification. The `ddtrace.settings` package was also removed.","error":"Pin.app is removed."},{"fix":"Ensure `ddtrace.patch_all()` is called only once during application startup. Implement a guard to prevent multiple invocations, or leverage `ddtrace-run` which handles patching automatically.","cause":"Calling `ddtrace.patch_all()` multiple times within an application, especially in test suites or certain framework setups, can lead to unexpected behavior including infinite loops in `ddtrace` versions 2.15.1 and later.","error":"Repeated calls to patch_all() eventually seem to infinite loop"},{"fix":"Upgrade `ddtrace` to a version that supports Python 3.14 (e.g., v4.x or a later v3.x release that includes the compatibility fix).","cause":"In `ddtrace` versions prior to Python 3.14 compatibility fixes, the library attempted to access a private `asyncio` attribute (`asyncio.events.BaseDefaultEventLoopPolicy`) which was renamed to `_BaseDefaultEventLoopPolicy` in Python 3.14.","error":"ddtrace 3.18.1 fails to import on Python 3.14.0 due to attempting to access asyncio.events.BaseDefaultEventLoopPolicy"}],"ecosystem":"pypi","meta_description":null,"install_score":80,"install_tag":"verified","quickstart_score":0,"quickstart_tag":"stale","pypi_latest":null,"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":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":"58.8M"},{"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":null,"mem_mb":null,"disk_size":"55M"},{"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":null,"mem_mb":null,"disk_size":"64.0M"},{"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":null,"mem_mb":null,"disk_size":"61M"},{"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":null,"mem_mb":null,"disk_size":"55.1M"},{"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":null,"mem_mb":null,"disk_size":"52M"},{"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":null,"mem_mb":null,"disk_size":"54.8M"},{"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":null,"mem_mb":null,"disk_size":"52M"},{"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":null,"mem_mb":null,"disk_size":"58.3M"},{"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":null,"mem_mb":null,"disk_size":"55M"}]},"quickstart_checks":{"last_tested":"2026-04-23","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}]}}