Python Instrumentation
Instrument Flask, FastAPI, Django, requests, SQLAlchemy, and more automatically using the OpenTelemetry bootstrap tool. No config file. No import order to manage.
1. Install
bash
pip install opentelemetry-distro opentelemetry-exporter-otlp
# Auto-install instrumentation packages for your dependencies
opentelemetry-bootstrap -a installopentelemetry-bootstrap -a install scans your installed packages and installs the matching OTel instrumentation — e.g. if you have FastAPI installed, it addsopentelemetry-instrumentation-fastapi automatically.2. Set environment variables
.env
OTEL_SERVICE_NAME=my-python-service
OTEL_EXPORTER_OTLP_ENDPOINT=https://la-ingest-gateway.lightarch.workers.dev
OTEL_EXPORTER_OTLP_HEADERS=x-la-dsn=la_live_YOUR_TOKEN_HERE
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobufOTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf is required — the Python distro defaults to gRPC, which Lightarch doesn't accept.3. Run your app
Prefix your normal start command with opentelemetry-instrument:
bash
# FastAPI
opentelemetry-instrument uvicorn main:app --host 0.0.0.0 --port 8000
# Flask
opentelemetry-instrument flask run
# Django
opentelemetry-instrument python manage.py runserver
# Any Python script
opentelemetry-instrument python your_script.pyNo changes to your application code required.
Screenshot needed
Traces page showing Python service spans with service='my-python-service', environment='production', waterfall showing FastAPI routes.
Verify it's working
bash
la query "SELECT service, severity, body, duration_ms FROM recent_spans WHERE service = 'my-python-service' ORDER BY timestamp DESC LIMIT 10"
la logs tail --service my-python-serviceCustom spans
python
from opentelemetry import trace
tracer = trace.get_tracer("my-service")
def process_payment(order_id: str):
with tracer.start_as_current_span("payment.process") as span:
span.set_attribute("order.id", order_id)
try:
result = charge_card(order_id)
span.set_attribute("payment.status", result["status"])
return result
except Exception as e:
span.record_exception(e)
span.set_status(trace.StatusCode.ERROR, str(e))
raiseAdvanced: manual config file (for custom resource attributes or fine-grained control)
eo_config.py
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.resources import Resource
import os
LA_DSN = os.environ["LA_DSN"]
resource = Resource.create({
"service.name": "my-python-service",
"deployment.environment": os.getenv("ENVIRONMENT", "production"),
})
provider = TracerProvider(resource=resource)
exporter = OTLPSpanExporter(
endpoint="https://la-ingest-gateway.lightarch.workers.dev/v1/traces",
headers={"x-la-dsn": LA_DSN},
)
provider.add_span_processor(BatchSpanProcessor(exporter))
trace.set_tracer_provider(provider)main.py
import eo_config # must be first import
from fastapi import FastAPI
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
app = FastAPI()
FastAPIInstrumentor.instrument_app(app)Import
eo_config as the first import — before FastAPI, requests, or any other library you want traced.