OpenTelemetry urllib Instrumentation
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.
Common errors
-
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.fixEnsure the package is installed using pip in the correct environment: `pip install opentelemetry-instrumentation-urllib` -
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.fixInstall the base OpenTelemetry instrumentation package: `pip install opentelemetry-instrumentation` -
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.fixEnsure that `set_tracer_provider()` is called only once, typically at the application's startup, before any instrumentation or tracing occurs. -
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.fixImport and instantiate the `URLLibInstrumentor` class, then call its `instrument()` method: `from opentelemetry.instrumentation.urllib import URLLibInstrumentor URLLibInstrumentor().instrument()` -
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.fixEnsure `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.
- 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.
- 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`.
- 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.
- 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.
Install
-
pip install opentelemetry-instrumentation-urllib opentelemetry-sdk
Imports
- URLLibInstrumentor
from opentelemetry.instrumentation.urllib import URLLibInstrumentor
Quickstart
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}")