OpenTelemetry urllib3 Instrumentation
This library provides automatic instrumentation for the `urllib3` HTTP client, enabling the collection of traces and metrics for HTTP requests made with `urllib3`. It's part of the OpenTelemetry Python Contrib repository and is currently in a beta development stage (`0.61b0`), with frequent updates.
Warnings
- gotcha The library is currently in beta (`0.61b0`), indicating that APIs and semantic conventions may still change between minor versions. While stable, users should anticipate potential adjustments in future releases.
- gotcha Unlike some OpenTelemetry auto-instrumentation approaches, `opentelemetry-instrumentation-urllib3` requires an explicit call to `URLLib3Instrumentor().instrument()` in your application code. It's not a 'zero-code' instrumentation via environment variables alone.
- gotcha To prevent capturing sensitive data or excessive telemetry from health checks, explicitly exclude URLs using the `OTEL_PYTHON_URLLIB3_EXCLUDED_URLS` or `OTEL_PYTHON_EXCLUDED_URLS` environment variables with comma-delimited regexes.
- deprecated Environment variables for capturing HTTP request and response headers (`OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_REQUEST`, `OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_RESPONSE`) and sanitizing them (`OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS`) are considered experimental and are subject to change according to OpenTelemetry specifications.
- breaking Auto-instrumentation might cause dependency conflicts, especially with `urllib3` versions. If your application relies on `urllib3` 1.x and the auto-instrumentation tries to install or uses `urllib3` 2.x, it can break the application due to `PYTHONPATH` overrides.
- gotcha If you are using other HTTP client instrumentations (e.g., `opentelemetry-instrumentation-requests`), you might encounter duplicate spans or unexpected behavior, as `requests` internally uses `urllib3`. Consider disabling `opentelemetry-instrumentation-urllib3` in such cases to avoid redundant tracing.
Install
-
pip install opentelemetry-instrumentation-urllib3 opentelemetry-sdk opentelemetry-exporter-otlp
Imports
- URLLib3Instrumentor
from opentelemetry.instrumentation.urllib3 import URLLib3Instrumentor
Quickstart
import os
import urllib3
from opentelemetry import trace
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.instrumentation.urllib3 import URLLib3Instrumentor
# Configure OpenTelemetry TracerProvider
resource = Resource.create({"service.name": "my-urllib3-app"})
provider = TracerProvider(resource=resource)
trace.set_tracer_provider(provider)
# Configure OTLP Exporter
# Ensure an OTLP collector is running at os.environ.get('OTEL_EXPORTER_OTLP_ENDPOINT', 'localhost:4317')
otlp_exporter = OTLPSpanExporter(
endpoint=os.environ.get('OTEL_EXPORTER_OTLP_ENDPOINT', 'localhost:4317'),
insecure=True # Use insecure for local testing if no TLS is configured
)
span_processor = BatchSpanProcessor(otlp_exporter)
provider.add_span_processor(span_processor)
# Initialize urllib3 instrumentation
URLLib3Instrumentor().instrument(
# Optional: Remove query parameters from span attribute for privacy/cardinality
url_filter=lambda url: url.split('?')[0]
)
# Perform an HTTP request with urllib3
http = urllib3.PoolManager()
print("Making a request to example.com...")
try:
response = http.request("GET", "http://www.example.com")
print(f"Request successful: {response.status}")
except Exception as e:
print(f"Request failed: {e}")
finally:
# It's good practice to shutdown the provider when the application exits
# This ensures all buffered spans are exported.
provider.shutdown()
print("OpenTelemetry provider shut down.")