OpenTelemetry HTTPX Instrumentation
OpenTelemetry HTTPX Instrumentation provides automatic tracing for HTTPX, a modern HTTP client for Python supporting both synchronous and asynchronous APIs. It is part of the OpenTelemetry Python Contrib project, which is actively developed and receives frequent beta releases, generally aligning with the core OpenTelemetry Python SDK's release cadence.
Warnings
- breaking OpenTelemetry's HTTP Semantic Conventions have been stabilized, leading to attribute name changes (e.g., `http.url` to `url.full`, `http.status_code` to `http.response.status_code`).
- gotcha HTTPX clients or their subclasses instantiated *before* `HTTPXClientInstrumentor().instrument()` is called will not be instrumented. This is particularly relevant when using libraries that internally create HTTPX clients (e.g., `openai-python`).
- gotcha Pre-fork servers (like Gunicorn with multiple workers) can cause issues with metrics generation when using OpenTelemetry auto-instrumentation due to threading and lock inconsistencies in child processes.
- gotcha By default, sensitive HTTP headers and request/response bodies are not captured or are sanitized. Directly logging or capturing raw payloads can expose sensitive data.
Install
-
pip install opentelemetry-instrumentation-httpx opentelemetry-sdk opentelemetry-exporter-otlp-proto-http httpx
Imports
- HTTPXClientInstrumentor
from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentor
- SyncOpenTelemetryTransport
from opentelemetry.instrumentation.httpx import SyncOpenTelemetryTransport
- AsyncOpenTelemetryTransport
from opentelemetry.instrumentation.httpx import AsyncOpenTelemetryTransport
Quickstart
import asyncio
import httpx
from opentelemetry import trace
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import ConsoleSpanExporter, BatchSpanProcessor
from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentor
import os
# Configure OpenTelemetry SDK
resource = Resource.create({"service.name": os.environ.get("OTEL_SERVICE_NAME", "httpx-client-app")})
provider = TracerProvider(resource=resource)
processor = BatchSpanProcessor(ConsoleSpanExporter())
provider.add_span_processor(processor)
trace.set_tracer_provider(provider)
# Instrument all HTTPX clients
HTTPXClientInstrumentor().instrument()
async def make_async_request():
print("\nMaking async HTTPX request...")
async with httpx.AsyncClient() as client:
response = await client.get("https://example.com")
print(f"Async request status: {response.status_code}")
def make_sync_request():
print("\nMaking sync HTTPX request...")
with httpx.Client() as client:
response = client.get("https://example.com")
print(f"Sync request status: {response.status_code}")
if __name__ == "__main__":
make_sync_request()
asyncio.run(make_async_request())
print("\nTraces should be printed above (if ConsoleSpanExporter is used).")