# Add Request Tracing to an Axum API from a Linear Issue

Yes. An agent picks up the Linear issue, adds TraceLayer request tracing to your Axum API, runs cargo test and opens a pull request.

[Run this on Rush](https://cloud.getrush.ai/run/add-request-tracing/axum/), in a Project that has your repository.

## What the agent does

The agent starts from the Linear issue and the repository in its own sandbox, and reads how HTTP logging is wired today. In a codebase like launchbadge/realworld-axum-sqlx (edition 2021, axum 0.3.4, tower-http 0.2 with the `trace` feature already in `Cargo.toml`), `src/http/mod.rs` already applies `TraceLayer::new_for_http()` in a `ServiceBuilder` and comments `RUST_LOG=tower_http=debug`. `src/main.rs` still calls `env_logger::init()` after `dotenv`, and comments in `src/http/error.rs` assume TraceLayer links errors to the request. There are no automated tests in the tree.

The gap against the issue is usually request IDs on spans and JSON logs through `tracing-subscriber` instead of (or in addition to) env_logger's plain lines. The agent plans: keep or upgrade `tower-http`'s TraceLayer, attach a request id extension and make it a span field, replace `env_logger::init()` with a `tracing-subscriber` registry that emits JSON and respects `RUST_LOG`, and document the env var in the README or `.env.example` if one exists.

It implements that in `src/main.rs` and `src/http/mod.rs`, adjusting for the crate's older axum 0.3 `AddExtensionLayer` style rather than rewriting the whole router. It adds tests that build the router (or a minimal stack) with TraceLayer, fire a request and assert a request id header or span field is present, starting Postgres in the sandbox when the test path needs SQLx migrations the same way `main` runs `sqlx::migrate!()`.

Last, it runs `cargo test` with Postgres available, fixes compile errors from subscriber feature flags, and opens a pull request that links the Linear issue and records the `RUST_LOG` values that produce JSON request lines.

## Start it with one API call

`POST https://api.prix.dev/o/{org}/sessions`

```json
{
  "agent": "claude",
  "input": "A Linear issue labeled agent says: \"Add Request Tracing to an Axum API. Add tower-http's TraceLayer with a request ID on every span and JSON logs through tracing-subscriber, configurable with RUST_LOG.\" Do the work in this repository, add tests for it, run cargo test with Postgres started in the sandbox, and open a pull request that links back to the issue.",
  "resources": [
    {
      "url": "https://github.com/your-org/your-app"
    }
  ]
}
```

1. **Get an API key.** In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
2. **Send the request.** POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
3. **Read what came back.** Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.

## What comes back

What comes back is a pull request on its own branch. The description notes that TraceLayer was already present but logging still went through env_logger, then shows the subscriber swap, request id on spans and any Cargo feature adds. The Linear issue is linked from the PR body.

The transcript keeps Postgres startup, migrations if run, and every `cargo test` invocation with its output. Missing proof stays visible in the session rather than as a silent green merge.

Before merging, a reviewer checks that `RUST_LOG` still filters noise, that request ids do not leak secrets, that error paths in `http/error.rs` still correlate with spans, and that tests fail if TraceLayer is removed from the stack.

## Run it on every Linear issue labelled agent

In the console, an automation with a `linear` trigger on `linear.issue.labeled` and the label `agent` starts one run per labelled issue, with the issue as its context, in the Project's repository. Changes made by an app integration never fire it, so the agent's own updates do not start new runs.

From your own server, the same run is one `POST /o/{org}/sessions` per issue: put the repository in `resources`, and add the issue's `https://linear.app/<workspace>/issue/<ID>` URL there too to have Rush read it through your Linear connection into the prompt. A webhook on the API key posts `run.completed` or `run.failed` when the turn finishes, with the `session_url` to read the result.

## Why run it on Rush?

This crate expects Postgres for a real boot (`PgPoolOptions` and embedded migrations in `main`). A Rush sandbox starts Postgres, runs `cargo test` and keeps the log, so subscriber feature mismatches and migration failures show up without touching a shared developer database.

A Linear label becomes a PR with the tracing change isolated on its own branch. Several labelled Rust API issues can run at once, each with its own sandbox and branch, up to the key's `max_concurrent` limit, and the transcript is the proof that `RUST_LOG` was exercised.

## Frequently asked questions

### The repo already has TraceLayer. Will it add a second one?

No. The agent reads `src/http/mod.rs` first. If TraceLayer is already on the `ServiceBuilder`, it extends that layer with request ids and fixes the subscriber side instead of stacking another TraceLayer.

### Why start Postgres for tracing tests?

Because this RealWorld app's serve path and migrations assume a live `DATABASE_URL`. Tests that build the full router need the same dependency the binary does; the sandbox starts Postgres so those tests are real.

### Does it keep env_logger?

Not as the primary request logger. The issue asks for `tracing-subscriber` JSON controlled by `RUST_LOG`; the agent removes or demotes `env_logger::init()` and documents the new variable.

### Which tower-http version does it target?

Whatever `Cargo.toml` already pins (0.2.0 with `features = ["trace"]` in the Launchbadge example). It upgrades only if the request-id API the team wants needs a newer crate, and the PR says why.
