Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 39 additions & 17 deletions docs/integrations/http-clients/httpx.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
---
title: "Instrument HTTPX: see every outgoing request your app makes"
description: "Add a few lines to your HTTPX code and see every outgoing HTTP request in Logfire: the URL, status, how long it took, and any errors."
title: "Instrument HTTPX and HTTPX2: see every outgoing request your app makes"
description: "Add a few lines to your HTTPX or HTTPX2 code and see every outgoing HTTP request in Logfire: the URL, status, how long it took, and any errors."
integration: otel
---
# HTTPX
# HTTPX and HTTPX2

See every HTTP request your app makes with [HTTPX][httpx]: the URL, the response status, how long it
took, and any errors, as a **span** (one unit of work with a name, a start, and a duration) in
Logfire. Related spans link together into a **trace** (the full journey of one request), so a slow
outgoing call shows up right next to the code that triggered it.
See every HTTP request your app makes with [HTTPX][httpx] or [HTTPX2][httpx2]: the URL, the response
status, how long it took, and any errors, as a **span** (one unit of work with a name, a start, and a
duration) in Logfire. Related spans link together into a **trace** (the full journey of one request),
so a slow outgoing call shows up right next to the code that triggered it.

This works with both the synchronous `httpx.Client` and the asynchronous `httpx.AsyncClient`.
This works with the synchronous `Client` and asynchronous `AsyncClient` from either library. If both
libraries are installed, one call to `logfire.instrument_httpx()` instruments both when
`opentelemetry-instrumentation-httpx` is version 0.65b0 or newer. With an earlier version, Logfire
instruments HTTPX and warns that it skipped HTTPX2.

## What you'll capture

Expand All @@ -26,12 +29,21 @@ Install `logfire` with the `httpx` extra:

{{ install_logfire(extras=['httpx']) }}

The extra installs the OpenTelemetry integration that collects request data. It does not install
`httpx` or `httpx2`; keep the client library you use as an application dependency.

HTTPX2 support requires `opentelemetry-instrumentation-httpx` 0.65b0 or newer. A fresh installation
normally selects a compatible version. If an existing environment keeps an older version, use the
upgrade command in [Troubleshooting](#troubleshooting).

## Usage

Add two lines to your app: `logfire.configure()` to connect to your project, and
[`logfire.instrument_httpx()`][logfire.Logfire.instrument_httpx] to record every request.
[`logfire.instrument_httpx()`][logfire.Logfire.instrument_httpx] to record every request. With no
client argument, Logfire instruments both libraries when they are installed. Pass a client instance
to instrument only that client.

=== "Instrument every client"
=== "Instrument all installed clients"

```py title="main.py" hl_lines="8" skip-run="true" skip-reason="external-connection"
import asyncio
Expand All @@ -57,26 +69,26 @@ Add two lines to your app: `logfire.configure()` to connect to your project, and
asyncio.run(main())
```

=== "Instrument a single client"
=== "Instrument one HTTPX2 client"

```py title="main.py" hl_lines="12 18" skip-run="true" skip-reason="external-connection"
import asyncio

import httpx
import httpx2

import logfire

logfire.configure()

url = 'https://httpbin.org/get'

with httpx.Client() as client:
with httpx2.Client() as client:
logfire.instrument_httpx(client)
client.get(url)


async def main():
async with httpx.AsyncClient() as client:
async with httpx2.AsyncClient() as client:
logfire.instrument_httpx(client)
await client.get(url)

Expand All @@ -86,6 +98,8 @@ Add two lines to your app: `logfire.configure()` to connect to your project, and

Run it with `python main.py`.

You can also pass one `httpx.Client` or `httpx.AsyncClient`; the Logfire call stays the same.

## Verify it worked

Run your program, then open your project in the
Expand All @@ -99,16 +113,23 @@ Not seeing your requests in Logfire? Check these first:

- **`logfire.configure()` runs before `logfire.instrument_httpx()`.** Configure the connection first,
then instrument.
- **You instrument the client you actually call.** `instrument_httpx()` with no argument covers all
clients; if you pass a specific client, make sure it's the one making the request.
- **You instrument the client you actually call.** `instrument_httpx()` with no argument covers both
installed libraries; if you pass a specific client, make sure it's the one making the request.
- **HTTPX2 reports that it needs newer OpenTelemetry instrumentation.** Upgrade Logfire and the HTTPX
integration together so their OpenTelemetry dependencies remain compatible:

```bash
pip install -U 'logfire[httpx]' 'opentelemetry-instrumentation-httpx>=0.65b0'
```
- **Your write token is set.** In local development, run `logfire projects use <your-project>`; in
production, set the `LOGFIRE_TOKEN` environment variable. See [Getting Started](../../index.md).
- **You actually made a request.** Spans appear only after a request completes.

## Advanced

The [`logfire.instrument_httpx()`][logfire.Logfire.instrument_httpx] method accepts several parameters
to control what's captured.
to control what's captured. The same capture settings and hooks apply to HTTPX and HTTPX2. The
examples below use HTTPX.

### Capture everything

Expand Down Expand Up @@ -226,4 +247,5 @@ client.post('https://httpbin.org/post', data='Hello, World!')
- Underlying OpenTelemetry package: [HTTPX instrumentation][opentelemetry-httpx]

[httpx]: https://www.python-httpx.org/
[httpx2]: https://github.com/pydantic/httpx2
Comment thread
alexmojaki marked this conversation as resolved.
[opentelemetry-httpx]: https://opentelemetry-python-contrib.readthedocs.io/en/latest/instrumentation/httpx/httpx.html
2 changes: 1 addition & 1 deletion docs/integrations/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ The below table lists these integrations and any corresponding `logfire.instrume
| [FastAPI](web-frameworks/fastapi.md) | Web Framework | [`logfire.instrument_fastapi()`][logfire.Logfire.instrument_fastapi] |
| [FastStream](event-streams/faststream.md) | Task Queue | N/A (built in, config needed) |
| [Flask](web-frameworks/flask.md) | Web Framework | [`logfire.instrument_flask()`][logfire.Logfire.instrument_flask] |
| [HTTPX](http-clients/httpx.md) | HTTP Client | [`logfire.instrument_httpx()`][logfire.Logfire.instrument_httpx] |
| [HTTPX and HTTPX2](http-clients/httpx.md) | HTTP Client | [`logfire.instrument_httpx()`][logfire.Logfire.instrument_httpx] |
| [LangChain](llms/langchain.md) | AI Framework | N/A (built-in OpenTelemetry support) |
| [LlamaIndex](llms/llamaindex.md) | AI Framework | N/A (requires LlamaIndex OpenTelemetry package) |
| [LiteLLM](llms/litellm.md) | AI Gateway | N/A (requires LiteLLM callback setup) |
Expand Down
2 changes: 1 addition & 1 deletion docs/nav.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@
{
"label": "HTTP Clients",
"items": [
{ "label": "HTTPX", "link": "/logfire/integrations/http-clients/httpx/" },
{ "label": "HTTPX and HTTPX2", "link": "/logfire/integrations/http-clients/httpx/" },
{ "label": "Requests", "link": "/logfire/integrations/http-clients/requests/" },
{ "label": "AIOHTTP", "link": "/logfire/integrations/http-clients/aiohttp/" }
]
Expand Down
Loading