OpenTelemetry urllib3 Instrumentation

raw JSON →
0.61b0 verified Tue May 12 auth: no python install: verified

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.

pip install opentelemetry-instrumentation-urllib3 opentelemetry-sdk opentelemetry-exporter-otlp
error ModuleNotFoundError: No module named 'opentelemetry.instrumentation.urllib3'
cause This error occurs when the `opentelemetry-instrumentation-urllib3` package is not installed in the Python environment, or the environment where it's installed is not the one running the application.
fix
Install the package using pip: pip install opentelemetry-instrumentation-urllib3.
error ImportError: cannot import name '_SUPPRESS_HTTP_INSTRUMENTATION_KEY' from 'opentelemetry.context'
cause This `ImportError` indicates a version incompatibility between `opentelemetry-api` and the `opentelemetry-instrumentation-urllib3` library. The `_SUPPRESS_HTTP_INSTRUMENTATION_KEY` was introduced or moved in a specific version of the OpenTelemetry API.
fix
Ensure all OpenTelemetry related packages are compatible by upgrading them to their latest versions or installing a consistent set of versions, often by reinstalling the opentelemetry-distro and then the specific instrumentation: pip install --upgrade opentelemetry-distro opentelemetry-instrumentation-urllib3.
error ImportError: cannot import name 'DEFAULT_CIPHERS' from 'urllib3.util.ssl_'
cause This error typically arises from a conflict in `urllib3` versions when using OpenTelemetry auto-instrumentation alongside other libraries (like `boto3`) that might depend on an older or different `urllib3` version. The instrumentation might attempt to use a feature or path in `urllib3.util.ssl_` that doesn't exist in the installed version.
fix
This often requires resolving dependency conflicts by either upgrading urllib3 to a compatible version (e.g., pip install --upgrade urllib3) or, if using an auto-instrumentation agent, ensuring that the application's urllib3 version is compatible with the one expected by the instrumentation. In some cases, adjusting the environment's PYTHONPATH or using a virtual environment with strict dependency pinning can help.
error from opentelemetry.urllib3 import URLLib3Instrumentor
cause This is a common wrong import pattern where developers forget to include the `instrumentation` sub-package path, leading to a `ModuleNotFoundError` for `opentelemetry.urllib3` as the `URLLib3Instrumentor` class is located within `opentelemetry.instrumentation.urllib3`.
fix
The correct import statement is from opentelemetry.instrumentation.urllib3 import URLLib3Instrumentor.
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.
fix Refer to the official OpenTelemetry Python documentation and release notes for any breaking changes or updated best practices when upgrading.
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.
fix Ensure `URLLib3Instrumentor().instrument()` is called early in your application's lifecycle, before `urllib3` HTTP requests are made, typically alongside your OpenTelemetry SDK setup.
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.
fix Set `export OTEL_PYTHON_URLLIB3_EXCLUDED_URLS="/healthz,.*sensitive-data.*"` in your environment, or pass a `url_filter` callable during instrumentation.
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.
fix Stay updated with OpenTelemetry specification changes regarding HTTP header attributes. Use with caution in production environments where stability is critical.
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.
fix Explicitly pin `urllib3` versions in your `requirements.txt`. If using OpenTelemetry auto-instrumentation agents, configure them to avoid installing or overriding `urllib3` versions, or ensure a compatible version is used throughout.
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.
fix Use the `OTEL_PYTHON_DISABLED_INSTRUMENTATIONS=urllib3` environment variable if another, higher-level HTTP client instrumentation (like `requests`) is preferred for tracing, to prevent `urllib3` from generating its own spans for the same outgoing calls.
gotcha Traces generated by `opentelemetry-instrumentation-urllib3` (or any other instrumentation) require an OpenTelemetry collector or an OTLP-compatible endpoint to be running and accessible for successful export. If the exporter endpoint is unavailable, traces will be generated by the instrumentation but will not be visible outside the application.
fix Ensure an OpenTelemetry collector is running and accessible at the configured `OTEL_EXPORTER_OTLP_ENDPOINT` (default is `localhost:4317`), or configure a different exporter if needed. Verify network connectivity and port availability for the exporter.
gotcha Traces generated by the instrumentation library will not be visible if the configured OpenTelemetry Collector or OTLP endpoint is unavailable or unreachable, resulting in `StatusCode.UNAVAILABLE` errors during export. This is an SDK-level issue, but it directly impacts the successful collection of `urllib3` telemetry, leading to a lack of observable data.
fix Ensure the OpenTelemetry Collector is running and accessible at the configured OTLP endpoint (default `localhost:4317`), or verify that the `OTEL_EXPORTER_OTLP_ENDPOINT` environment variable is correctly set and reachable.
python os / libc status wheel install import disk
3.10 alpine (musl) wheel - 0.40s 52.1M
3.10 alpine (musl) - - 0.43s 51.9M
3.10 slim (glibc) wheel 5.6s 0.29s 50M
3.10 slim (glibc) - - 0.29s 50M
3.11 alpine (musl) wheel - 0.60s 55.6M
3.11 alpine (musl) - - 0.73s 55.4M
3.11 slim (glibc) wheel 4.9s 0.53s 53M
3.11 slim (glibc) - - 0.54s 53M
3.12 alpine (musl) wheel - 0.79s 47.1M
3.12 alpine (musl) - - 0.80s 46.9M
3.12 slim (glibc) wheel 4.1s 0.72s 45M
3.12 slim (glibc) - - 0.76s 45M
3.13 alpine (musl) wheel - 0.41s 46.9M
3.13 alpine (musl) - - 0.46s 46.5M
3.13 slim (glibc) wheel 4.0s 0.42s 45M
3.13 slim (glibc) - - 0.47s 44M
3.9 alpine (musl) wheel - 0.36s 51.3M
3.9 alpine (musl) - - 0.39s 51.2M
3.9 slim (glibc) wheel 6.4s 0.37s 49M
3.9 slim (glibc) - - 0.34s 49M

This quickstart demonstrates how to set up OpenTelemetry with an OTLP gRPC exporter and instrument `urllib3` to trace HTTP requests. It initializes a `TracerProvider`, adds an `OTLPSpanExporter`, and then instruments `urllib3` before making an HTTP request. Remember to run an OpenTelemetry Collector or compatible backend to receive traces.

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.")