OpenTelemetry urllib Instrumentation
raw JSON → 0.61b0 verified Tue May 12 auth: no python install: verified
This library enables automatic tracing of HTTP requests made using Python's built-in `urllib` library. Part of the `opentelemetry-python-contrib` project, it is currently in beta (version 0.61b0 as of March 2026) and receives frequent updates.
pip install opentelemetry-instrumentation-urllib opentelemetry-sdk cli
opentelemetry-instrument Common errors
error ModuleNotFoundError: No module named 'opentelemetry.instrumentation.urllib' ↓
cause This error occurs when the `opentelemetry-instrumentation-urllib` package is not installed or is installed in a different Python environment than the one running the application.
fix
Ensure the package is installed using pip in the correct environment:
pip install opentelemetry-instrumentation-urllib error ModuleNotFoundError: No module named 'opentelemetry.instrumentation' ↓
cause This general OpenTelemetry instrumentation error means the core `opentelemetry-instrumentation` package, a dependency for all specific instrumentations including urllib, is missing or in an inaccessible environment.
fix
Install the base OpenTelemetry instrumentation package:
pip install opentelemetry-instrumentation error WARNING:opentelemetry.trace:Overriding of current TracerProvider is not allowed. ↓
cause This warning indicates that `set_tracer_provider()` is being called multiple times within the application's lifecycle, often due to re-initializing OpenTelemetry components or instrumenting an application that forks processes.
fix
Ensure that
set_tracer_provider() is called only once, typically at the application's startup, before any instrumentation or tracing occurs. error AttributeError: module 'opentelemetry.instrumentation.urllib' has no attribute 'instrument' ↓
cause This error happens when attempting to call `instrument()` directly on the `opentelemetry.instrumentation.urllib` module instead of creating an instance of `URLLibInstrumentor` and calling its `instrument()` method.
fix
Import and instantiate the
URLLibInstrumentor class, then call its instrument() method: from opentelemetry.instrumentation.urllib import URLLibInstrumentor
URLLibInstrumentor().instrument() error WARNING:opentelemetry.instrumentation.instrumentor:Attempting to instrument while already instrumented. ↓
cause This warning indicates that the instrumentation for urllib (or another library) is being applied more than once, which can happen if `URLLibInstrumentor().instrument()` is called redundantly or if using auto-instrumentation in a way that re-instruments already patched modules.
fix
Ensure
URLLibInstrumentor().instrument() is called only once during the application's initialization phase. If using opentelemetry-bootstrap, verify that manual instrumentation calls are not duplicating its efforts. Warnings
gotcha Instrumentation must be enabled before the `urllib` module is first used. If `urllib` is imported or used before `URLLibInstrumentor().instrument()` is called, requests made prior to instrumentation will not be traced. ↓
fix Ensure `URLLibInstrumentor().instrument()` is called early in your application's lifecycle, typically during application startup before any `urllib` calls are made.
gotcha The library is currently in beta (`0.x.y` versions), meaning its API and produced telemetry (semantic conventions) may be subject to breaking changes between minor versions. This can impact dashboards or alerting built on specific attribute names. ↓
fix Review the `opentelemetry-python-contrib` changelog before upgrading to new beta versions. Consider pinning to specific beta versions if stability is critical.
gotcha To capture HTTP request and response headers as span attributes, you must explicitly configure environment variables like `OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_REQUEST` and `OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_RESPONSE`. ↓
fix Set these environment variables to a comma-delimited list of header names or a regex (e.g., `'.*'` for all headers). Use `OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS` to redact sensitive header values.
gotcha When using pre-forking web servers (e.g., Gunicorn with multiple workers), auto-instrumentation can lead to inconsistencies or break metrics generation due to issues with background threads and locks in child processes. ↓
fix Consider using programmatic auto-instrumentation in each worker, or restrict Gunicorn to a single worker for simpler setups. Refer to OpenTelemetry documentation on troubleshooting pre-fork issues.
gotcha By default, OpenTelemetry instrumentations do not provide a backend for storing, querying, or visualizing telemetry data. You need to integrate with an OpenTelemetry-compatible backend (e.g., Jaeger, Prometheus, commercial APMs) to utilize the collected traces. ↓
fix Ensure you have an OpenTelemetry Collector or an exporter configured to send data to your chosen observability backend.
Install compatibility verified last tested: 2026-05-12 v0.62b1 (up to date)
python os / libc status wheel install import disk mem side effects
3.10 alpine (musl) wheel - 0.33s 24.2M 9.8M clean
3.10 alpine (musl) - - 0.39s 24.0M 9.7M -
3.10 slim (glibc) wheel 2.8s 0.23s 25M 9.8M clean
3.10 slim (glibc) - - 0.27s 25M 9.7M -
3.11 alpine (musl) wheel - 0.49s 26.7M 11.4M clean
3.11 alpine (musl) - - 0.63s 26.5M 11.3M -
3.11 slim (glibc) wheel 2.8s 0.46s 27M 11.4M clean
3.11 slim (glibc) - - 0.46s 27M 11.3M -
3.12 alpine (musl) wheel - 0.66s 18.4M 13.1M clean
3.12 alpine (musl) - - 0.77s 18.2M 13.1M -
3.12 slim (glibc) wheel 2.4s 0.62s 19M 13.1M clean
3.12 slim (glibc) - - 0.75s 19M 13.1M -
3.13 alpine (musl) wheel - 0.35s 18.2M 9.7M clean
3.13 alpine (musl) - - 0.41s 17.8M 9.6M -
3.13 slim (glibc) wheel 2.3s 0.34s 19M 9.7M clean
3.13 slim (glibc) - - 0.41s 18M 9.6M -
3.9 alpine (musl) wheel - 0.30s 23.7M 9.8M clean
3.9 alpine (musl) - - 0.36s 23.5M 9.7M -
3.9 slim (glibc) wheel 3.1s 0.27s 24M 9.8M clean
3.9 slim (glibc) - - 0.32s 24M 9.7M -
Imports
- URLLibInstrumentor
from opentelemetry.instrumentation.urllib import URLLibInstrumentor
Quickstart last tested: 2026-04-24
import os
from urllib import request
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor
from opentelemetry.instrumentation.urllib import URLLibInstrumentor
# Configure OpenTelemetry SDK
provider = TracerProvider()
processor = SimpleSpanProcessor(ConsoleSpanExporter())
provider.add_span_processor(processor)
trace.set_tracer_provider(provider)
# Instrument urllib
URLLibInstrumentor().instrument()
# Make a request using urllib.request
tracer = trace.get_tracer(__name__)
with tracer.start_as_current_span("my-urllib-request"):
try:
req = request.Request('http://httpbin.org/get')
response = request.urlopen(req)
print(f"Response Status: {response.getcode()}")
print(f"Response Data (first 100 chars): {response.read(100).decode()}")
except Exception as e:
print(f"Error during request: {e}")