OpenTelemetry HTTPX Instrumentation¶
This library allows tracing HTTP requests made by the httpx library.
Installation¶
pip install opentelemetry-instrumentation-httpx
Usage¶
Instrumenting all clients¶
When using the instrumentor, all clients will automatically trace requests.
import httpx
from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentor
url = "https://some.url/get"
HTTPXClientInstrumentor().instrument()
with httpx.Client() as client:
response = client.get(url)
async with httpx.AsyncClient() as client:
response = await client.get(url)
Instrumenting single clients¶
If you only want to instrument requests for specific client instances, you can
use the instrument_client
method.
import httpx
from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentor
url = "https://some.url/get"
with httpx.Client(transport=telemetry_transport) as client:
HTTPXClientInstrumentor.instrument_client(client)
response = client.get(url)
async with httpx.AsyncClient(transport=telemetry_transport) as client:
HTTPXClientInstrumentor.instrument_client(client)
response = await client.get(url)
Uninstrument¶
If you need to uninstrument clients, there are two options available.
import httpx
from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentor
HTTPXClientInstrumentor().instrument()
client = httpx.Client()
# Uninstrument a specific client
HTTPXClientInstrumentor.uninstrument_client(client)
# Uninstrument all clients
HTTPXClientInstrumentor().uninstrument()
Using transports directly¶
If you don’t want to use the instrumentor class, you can use the transport classes directly.
import httpx
from opentelemetry.instrumentation.httpx import (
AsyncOpenTelemetryTransport,
SyncOpenTelemetryTransport,
)
url = "https://some.url/get"
transport = httpx.HTTPTransport()
telemetry_transport = SyncOpenTelemetryTransport(transport)
with httpx.Client(transport=telemetry_transport) as client:
response = client.get(url)
transport = httpx.AsyncHTTPTransport()
telemetry_transport = AsyncOpenTelemetryTransport(transport)
async with httpx.AsyncClient(transport=telemetry_transport) as client:
response = await client.get(url)
Request and response hooks¶
The instrumentation supports specifying request and response hooks. These are functions that get called back by the instrumentation right after a span is created for a request and right before the span is finished while processing a response.
Note
The request hook receives the raw arguments provided to the transport layer. The response hook receives the raw return values from the transport layer.
The hooks can be configured as follows:
from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentor
def request_hook(span, request):
# method, url, headers, stream, extensions = request
pass
def response_hook(span, request, response):
# method, url, headers, stream, extensions = request
# status_code, headers, stream, extensions = response
pass
HTTPXClientInstrumentor().instrument(request_hook=request_hook, response_hook=response_hook)
Or if you are using the transport classes directly:
from opentelemetry.instrumentation.httpx import SyncOpenTelemetryTransport
def request_hook(span, request):
# method, url, headers, stream, extensions = request
pass
def response_hook(span, request, response):
# method, url, headers, stream, extensions = request
# status_code, headers, stream, extensions = response
pass
transport = httpx.HTTPTransport()
telemetry_transport = SyncOpenTelemetryTransport(
transport,
request_hook=request_hook,
response_hook=response_hook
)
API¶
Usage¶
Instrumenting all clients¶
When using the instrumentor, all clients will automatically trace requests.
import httpx
from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentor
url = "https://some.url/get"
HTTPXClientInstrumentor().instrument()
with httpx.Client() as client:
response = client.get(url)
async with httpx.AsyncClient() as client:
response = await client.get(url)
Instrumenting single clients¶
If you only want to instrument requests for specific client instances, you can
use the instrument_client
method.
import httpx
from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentor
url = "https://some.url/get"
with httpx.Client(transport=telemetry_transport) as client:
HTTPXClientInstrumentor.instrument_client(client)
response = client.get(url)
async with httpx.AsyncClient(transport=telemetry_transport) as client:
HTTPXClientInstrumentor.instrument_client(client)
response = await client.get(url)
Uninstrument¶
If you need to uninstrument clients, there are two options available.
import httpx
from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentor
HTTPXClientInstrumentor().instrument()
client = httpx.Client()
# Uninstrument a specific client
HTTPXClientInstrumentor.uninstrument_client(client)
# Uninstrument all clients
HTTPXClientInstrumentor().uninstrument()
Using transports directly¶
If you don’t want to use the instrumentor class, you can use the transport classes directly.
import httpx
from opentelemetry.instrumentation.httpx import (
AsyncOpenTelemetryTransport,
SyncOpenTelemetryTransport,
)
url = "https://some.url/get"
transport = httpx.HTTPTransport()
telemetry_transport = SyncOpenTelemetryTransport(transport)
with httpx.Client(transport=telemetry_transport) as client:
response = client.get(url)
transport = httpx.AsyncHTTPTransport()
telemetry_transport = AsyncOpenTelemetryTransport(transport)
async with httpx.AsyncClient(transport=telemetry_transport) as client:
response = await client.get(url)
Request and response hooks¶
The instrumentation supports specifying request and response hooks. These are functions that get called back by the instrumentation right after a span is created for a request and right before the span is finished while processing a response.
Note
The request hook receives the raw arguments provided to the transport layer. The response hook receives the raw return values from the transport layer.
The hooks can be configured as follows:
from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentor
def request_hook(span, request):
# method, url, headers, stream, extensions = request
pass
def response_hook(span, request, response):
# method, url, headers, stream, extensions = request
# status_code, headers, stream, extensions = response
pass
HTTPXClientInstrumentor().instrument(request_hook=request_hook, response_hook=response_hook)
Or if you are using the transport classes directly:
from opentelemetry.instrumentation.httpx import SyncOpenTelemetryTransport
def request_hook(span, request):
# method, url, headers, stream, extensions = request
pass
def response_hook(span, request, response):
# method, url, headers, stream, extensions = request
# status_code, headers, stream, extensions = response
pass
transport = httpx.HTTPTransport()
telemetry_transport = SyncOpenTelemetryTransport(
transport,
request_hook=request_hook,
response_hook=response_hook
)
API¶
- class opentelemetry.instrumentation.httpx.RequestInfo(method, url, headers, stream, extensions)[source]¶
Bases:
tuple
- stream: Optional[Union[httpx.SyncByteStream, httpx.AsyncByteStream]]¶
Alias for field number 3
- class opentelemetry.instrumentation.httpx.ResponseInfo(status_code, headers, stream, extensions)[source]¶
Bases:
tuple
- class opentelemetry.instrumentation.httpx.SyncOpenTelemetryTransport(transport, tracer_provider=None, request_hook=None, response_hook=None)[source]¶
Bases:
httpx.BaseTransport
Sync transport class that will trace all requests made with a client.
- Parameters
transport (
BaseTransport
) – SyncHTTPTransport instance to wraptracer_provider (
Optional
[TracerProvider
]) – Tracer provider to userequest_hook (
Optional
[Callable
[[Span
,RequestInfo
],None
]]) – A hook that receives the span and request that is called right after the span is createdresponse_hook (
Optional
[Callable
[[Span
,RequestInfo
,ResponseInfo
],None
]]) – A hook that receives the span, request, and response that is called right before the span ends
- class opentelemetry.instrumentation.httpx.AsyncOpenTelemetryTransport(transport, tracer_provider=None, request_hook=None, response_hook=None)[source]¶
Bases:
httpx.AsyncBaseTransport
Async transport class that will trace all requests made with a client.
- Parameters
transport (
AsyncBaseTransport
) – AsyncHTTPTransport instance to wraptracer_provider (
Optional
[TracerProvider
]) – Tracer provider to userequest_hook (
Optional
[Callable
[[Span
,RequestInfo
],None
]]) – A hook that receives the span and request that is called right after the span is createdresponse_hook (
Optional
[Callable
[[Span
,RequestInfo
,ResponseInfo
],None
]]) – A hook that receives the span, request, and response that is called right before the span ends
- class opentelemetry.instrumentation.httpx.HTTPXClientInstrumentor(*args, **kwargs)[source]¶
Bases:
opentelemetry.instrumentation.instrumentor.BaseInstrumentor
An instrumentor for httpx Client and AsyncClient
See
BaseInstrumentor
- instrumentation_dependencies()[source]¶
Return a list of python packages with versions that the will be instrumented.
The format should be the same as used in requirements.txt or pyproject.toml.
For example, if an instrumentation instruments requests 1.x, this method should look like:
- def instrumentation_dependencies(self) -> Collection[str]:
return [‘requests ~= 1.0’]
This will ensure that the instrumentation will only be used when the specified library is present in the environment.
- Return type
- static instrument_client(client, tracer_provider=None, request_hook=None, response_hook=None)[source]¶
Instrument httpx Client or AsyncClient
- Parameters
client (
Union
[Client
,AsyncClient
]) – The httpx Client or AsyncClient instancetracer_provider (
Optional
[TracerProvider
]) – A TracerProvider, defaults to globalrequest_hook (
Optional
[Callable
[[Span
,RequestInfo
],None
]]) – A hook that receives the span and request that is called right after the span is createdresponse_hook (
Optional
[Callable
[[Span
,RequestInfo
,ResponseInfo
],None
]]) – A hook that receives the span, request, and response that is called right before the span ends
- Return type