Datadog Python APM Tracer (ddtrace)
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.
Warnings
- breaking 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.
- breaking Pin class removed in v4.0. Code using Pin.get_from(), Pin.override(), ddtrace.Pin raises ImportError.
- breaking Span.set_tag_str() removed in v4.0. Raises AttributeError.
- breaking ddtrace.settings package removed in v4.0. Code importing from ddtrace.settings raises ImportError.
- breaking patch_all() and patch() must be called BEFORE the library being instrumented is imported. Calling after import silently produces no instrumentation.
- breaking DD_CALL_BASIC_CONFIG removed in v2.0. Raises error if set.
- gotcha Datadog Agent must be running at localhost:8126 (default). Without it, traces are silently dropped — no error raised.
- gotcha Unified Service Tagging requires DD_SERVICE, DD_ENV, DD_VERSION env vars. Without them, services appear as unnamed in Datadog UI.
Install
-
pip install ddtrace
Imports
- ddtrace-run (preferred — auto-instrumentation)
# Preferred: use ddtrace-run CLI wrapper # This patches libraries at startup before your code imports them # Set env vars: # DD_SERVICE=my-service # DD_ENV=production # DD_VERSION=1.0.0 # DD_AGENT_HOST=localhost (default) # DD_TRACE_AGENT_PORT=8126 (default) # Run your app: # ddtrace-run python app.py # ddtrace-run gunicorn app:application # ddtrace-run uvicorn app:app # Verify config: # ddtrace-run --info
- Manual tracing (custom spans)
from ddtrace import tracer # Custom span with tracer.trace('my.operation', service='my-service', resource='checkout') as span: span.set_tag('user.id', '123') span.set_tag('order.id', 'ord-456') # do work # Decorator from ddtrace import tracer @tracer.wrap(service='my-service', resource='process_payment') def process_payment(order_id): pass # Error tracking try: risky_operation() except Exception as e: span.error = 1 span.set_tag('error.msg', str(e)) raise
Quickstart
# pip install ddtrace
# Requires Datadog Agent running at localhost:8126
# Option 1: ddtrace-run (recommended)
# DD_SERVICE=my-app DD_ENV=prod ddtrace-run python app.py
# Option 2: manual patch at top of entry point (before all other imports)
from ddtrace import patch
patch(all=True) # must be before any library imports
# OR selectively:
# patch(requests=True, sqlalchemy=True, redis=True)
import flask # patched because patch() was called first
from ddtrace import tracer
app = flask.Flask(__name__)
@app.route('/checkout')
def checkout():
with tracer.trace('checkout.process', resource='checkout') as span:
span.set_tag('user.id', flask.request.args.get('user_id'))
# Unified Service Tagging via env vars:
# DD_SERVICE, DD_ENV, DD_VERSION
return 'ok'
# Check agent connectivity:
# ddtrace-run --info