Skip to main content

OpenTelemetry for Python

OpenTelemetry for Python can auto-instrument most popular web frameworks and libraries — so you get rich distributed tracing without modifying your application code. Traces ship to CodeXray over OTLP.

Auto-instrumentation via the CLI

OpenTelemetry ships a command-line wrapper — opentelemetry-instrument — that instruments your Python application on the fly. Point it at your existing run command and traces start flowing, no code changes required.


Before You Begin​

You'll need:

  • A Python application (Python 3.8+) — any web framework, or a background service
  • The URL of your CodeXray collector (e.g., https://your-codexray.example.com)
  • A project API key from the CodeXray UI (Project Settings → API Keys)

Step 1 — Install the OpenTelemetry Packages​

pip install opentelemetry-distro opentelemetry-exporter-otlp
opentelemetry-bootstrap -a install

What these do:

  • opentelemetry-distro — the OpenTelemetry distribution (SDK + auto-instrumentation runner)
  • opentelemetry-exporter-otlp — the OTLP exporter (HTTP + gRPC)
  • opentelemetry-bootstrap -a install — detects the libraries your project uses and installs matching instrumentation packages for each

Step 2 — Configure via Environment Variables​

export OTEL_SERVICE_NAME="your-service-name"
export OTEL_EXPORTER_OTLP_ENDPOINT="https://your-codexray.example.com"
export OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf"
export OTEL_EXPORTER_OTLP_HEADERS="x-api-key=your-project-api-key"
export OTEL_METRICS_EXPORTER="none" # traces only for now
VariablePurpose
OTEL_SERVICE_NAMEThe name that appears in CodeXray's Applications list
OTEL_EXPORTER_OTLP_ENDPOINTYour CodeXray collector URL (no trailing slash)
OTEL_EXPORTER_OTLP_PROTOCOLhttp/protobuf (recommended) or grpc
OTEL_EXPORTER_OTLP_HEADERSAuthentication — your project API key as x-api-key
OTEL_RESOURCE_ATTRIBUTESOptional — add environment, version, etc.

Step 3 — Run Your Application with opentelemetry-instrument​

Prefix your normal start command with opentelemetry-instrument:

Django​

opentelemetry-instrument --traces_exporter otlp --metrics_exporter none \
./manage.py runserver --noreload 8000

Flask​

opentelemetry-instrument --traces_exporter otlp --metrics_exporter none \
flask run

For production Flask behind gunicorn:

opentelemetry-instrument --traces_exporter otlp --metrics_exporter none \
gunicorn -w 4 myapp:app

FastAPI​

opentelemetry-instrument --traces_exporter otlp --metrics_exporter none \
uvicorn myapp:app --host 0.0.0.0 --port 8000

Generic Python services​

Any Python entry point works — background workers, cron jobs, CLI tools:

opentelemetry-instrument --traces_exporter otlp --metrics_exporter none \
python your_worker.py

What Gets Instrumented​

opentelemetry-bootstrap -a install detects and instruments:

  • Web frameworks — Django, Flask, FastAPI, Starlette, Falcon, Pyramid, Tornado, AIOHTTP, Bottle, Sanic
  • HTTP clients — requests, urllib, urllib3, httpx, aiohttp-client
  • Databases — psycopg2 (Postgres), PyMySQL, MySQL-connector, SQLAlchemy, Django ORM, asyncpg, Redis (redis, aioredis), MongoDB (pymongo), SQLite3
  • Messaging — Kafka (confluent-kafka, aiokafka), RabbitMQ (pika), AWS SQS
  • RPC — gRPC (grpcio)
  • Task queues — Celery
  • Logging — Python logging module (for log-to-trace correlation)

See the list of instrumentations for the full, ever-growing set.


Running in a Container​

Drop the install step into your Dockerfile so the image is ready to run under opentelemetry-instrument:

FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt \
&& pip install opentelemetry-distro opentelemetry-exporter-otlp \
&& opentelemetry-bootstrap -a install
COPY . .
ENTRYPOINT ["opentelemetry-instrument", "--traces_exporter", "otlp", "--metrics_exporter", "none"]
CMD ["gunicorn", "-w", "4", "myapp:app"]

Then set the OTel env vars at runtime (Pod spec, Docker Compose, or your orchestration of choice).


Additional Resource Attributes​

Attach environment, version, and anything else you want on every span:

export OTEL_RESOURCE_ATTRIBUTES="deployment.environment=production,service.version=2.1.0,service.namespace=payments"

Verifying It's Working​

  1. Start your application with opentelemetry-instrument in front of your run command
  2. Make a request (hit an endpoint, trigger a job)
  3. In CodeXray, open Applications → find your service (by OTEL_SERVICE_NAME) → Traces tab
  4. Traces should appear within a minute

If nothing appears, check the application logs — the OTel SDK logs connectivity failures and configuration problems explicitly.


Manual Instrumentation (When You Need More)​

opentelemetry-instrument covers framework-level spans. For your own business logic, add spans manually:

from opentelemetry import trace

tracer = trace.get_tracer(__name__)

def process_order(order_id):
with tracer.start_as_current_span("process_order") as span:
span.set_attribute("order.id", order_id)
# ... your logic ...

Custom spans automatically join the surrounding request's trace — no extra configuration needed.


Next Steps​