Skip to content

feat(net): Tracing resilience layer (Slice 1, PR 5)#86

Merged
NotAProfDev merged 8 commits into
mainfrom
feat/net-http-tracing
Jul 5, 2026
Merged

feat(net): Tracing resilience layer (Slice 1, PR 5)#86
NotAProfDev merged 8 commits into
mainfrom
feat/net-http-tracing

Conversation

@NotAProfDev

@NotAProfDev NotAProfDev commented Jul 5, 2026

Copy link
Copy Markdown
Owner

Closes #83

Slice 1 PR 5 of the net-http resilience layers (spec: docs/superpowers/specs/2026-07-04-net-http-tracing-layer-design.md; ADR-0031 §6, ADR-0014). The outermost layer; built concurrently with the CircuitBreaker PR (independent files).

  • Tracing<S, T> + TracingLayer<T> (net-api::Layer) — one info span per logical request (method, route, status, ErrorKind, latency, attempts), attached to the inner future via tracing::Instrument so downstream events (incl. Retry's per-attempt) nest under it. Latency via net-api::Timer deltas.
  • Secret-safe by construction — reads only method, uri().path() (query dropped), status, ErrorKind, and the clock; never headers, never bodies. Body-transparent (Response<B> untouched).
  • Retry instrumentationdebug per-attempt/backoff events + an ambient Span::current().record("attempts", n) (a no-op without a Tracing span). Composition contract: Tracing owns the one span; inner layers emit events, not spans.
  • Routed to the ADR-0014 Telemetry plane (machinery metrics, lossy, never canonical). Module named trace to avoid shadowing the tracing crate.

Adds the tracing facade (runtime dep, zero executor) + tracing-subscriber (dev-dep). MockTimer-driven tests with inline service doubles + a capturing subscriber, including the load-bearing secret-safety test.

Next: Slice 2 — the stack()/build() assembly that wires the default layer order.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added an HTTP request tracing resilience layer that creates a per-request span capturing method, route (query excluded), status or error kind, latency, and integrates with retry attempt tracking.
    • Enhanced retry observability with per-attempt debug events and recorded final attempt count.
  • Bug Fixes
    • Improved telemetry safety by avoiding leaks of headers, bodies, query tokens, or sensitive error details.
  • Tests
    • Added unit tests validating span fields, body transparency, latency measurement, and retry nesting/attempt recording.
  • Documentation
    • Updated ADRs/specs and the changelog to reflect tracing-layer behavior and composition.

NotAProfDev and others added 6 commits July 4, 2026 19:29
Outermost ADR-0031 §6 layer: one info span per logical request (method,
route, status, ErrorKind, latency, attempts), routed to the ADR-0014
Telemetry plane. Timer-generic latency; query-stripped route; structural
secret-safety (reads only method/path/status/kind/clock). Includes Retry
per-attempt events + an ambient attempt-count record, under a documented
"inner layers emit events, not spans" composition contract. Built
concurrently with the CircuitBreaker PR (independent files).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Three-task TDD plan: (1) the Tracing layer + capturing-subscriber test
harness + secret-safety test; (2) Retry per-attempt events + ambient
attempt-count integration test; (3) ADR-0034 amendment, CHANGELOG, gate,
PR. Module named 'trace' to avoid shadowing the tracing crate.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 5, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 090c583d-41ca-4430-9167-cf2a716d55f3

📥 Commits

Reviewing files that changed from the base of the PR and between 7adfecf and c8ac1df.

📒 Files selected for processing (4)
  • CHANGELOG.md
  • crates/adapter/net/http/api/src/lib.rs
  • docs/adr/0034-http-construction-surface-auth-guarded-boot-coverage.md
  • docs/superpowers/plans/2026-07-04-net-http-tracing-layer.md
✅ Files skipped from review due to trivial changes (2)
  • CHANGELOG.md
  • docs/superpowers/plans/2026-07-04-net-http-tracing-layer.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • crates/adapter/net/http/api/src/lib.rs

📝 Walkthrough

Walkthrough

Adds a request-scoped Tracing middleware for net-http, wires tracing dependencies and exports, instruments Retry with tracing events and attempt recording, and updates tests, ADR, changelog, and design/spec docs.

Changes

Tracing Resilience Layer

Layer / File(s) Summary
Dependency wiring and public surface
Cargo.toml, crates/adapter/net/http/api/Cargo.toml, crates/adapter/net/http/api/src/lib.rs
Adds tracing and tracing-subscriber, declares the trace module, re-exports Tracing and TracingLayer, and documents the new module in the crate overview.
Tracing middleware core
crates/adapter/net/http/api/src/trace.rs
Adds ErrorKind label mapping plus TracingLayer and Tracing, which open an http.request span, measure latency, and record status or error_kind.
Retry telemetry
crates/adapter/net/http/api/src/retry.rs
Adds per-attempt debug events, records final attempt count on the current span, and emits a backoff debug event before sleeping.
Tracing tests
crates/adapter/net/http/api/src/trace.rs
Adds tracing capture helpers, stub services, and tests for span fields, latency, secret-safety, and retry behavior.
Docs and ADR updates
CHANGELOG.md, docs/adr/0034-*.md, docs/superpowers/plans/*, docs/superpowers/specs/*
Adds the Tracing changelog entry, ADR amendment, implementation plan, and design spec.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

  • NotAProfDev/oath#82: Updates the retry path that now emits tracing events and records attempt counts.

Suggested labels: enhancement

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed It uses a valid Conventional Commits-style prefix and accurately describes the Tracing layer change.
Linked Issues check ✅ Passed The PR adds the Tracing layer, retry tracing, secret-safe span fields, and required dependencies as requested in #83.
Out of Scope Changes check ✅ Passed The documentation and changelog updates are directly tied to the Tracing feature and do not appear unrelated.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/net-http-tracing

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
crates/adapter/net/http/api/src/retry.rs (1)

246-259: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use the stable kind_label mapping instead of Debug for error_kind.

The per-attempt event formats error_kind with ?e.kind() (Debug), while the sibling http.request span in trace.rs uses a dedicated kind_label() function specifically to produce "stable, low-cardinality string labels" for this dimension. That means the same logical field (error_kind) will carry two different value conventions across the two telemetry surfaces for the same request (e.g. Connection here vs connection on the outer span), undermining the ADR-0014 telemetry plane's consistency and any downstream aggregation/filtering keyed on this field.

Since kind_label is currently private to trace.rs, reusing it here would require exposing it as pub(crate).

♻️ Proposed fix
-                    Err(e) => tracing::event!(
-                        tracing::Level::DEBUG,
-                        attempt = u64::from(attempt),
-                        error_kind = ?e.kind(),
-                        "http.attempt"
-                    ),
+                    Err(e) => tracing::event!(
+                        tracing::Level::DEBUG,
+                        attempt = u64::from(attempt),
+                        error_kind = crate::trace::kind_label(e.kind()),
+                        "http.attempt"
+                    ),

And in trace.rs:

-fn kind_label(kind: ErrorKind) -> &'static str {
+pub(crate) fn kind_label(kind: ErrorKind) -> &'static str {

Please confirm ErrorKind's Debug output doesn't carry any per-variant payload data before deciding severity here (if it does, this becomes a secret-safety concern rather than just a consistency one).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/adapter/net/http/api/src/retry.rs` around lines 246 - 259, The
per-attempt `http.attempt` event in `retry.rs` is using `?e.kind()` for
`error_kind`, which is inconsistent with the stable label convention used by
`http.request` in `trace.rs`. Update the `tracing::event!` call in the retry
path to use the same `kind_label()` mapping for `ErrorKind`, and make that
helper `pub(crate)` in `trace.rs` so both telemetry surfaces emit the same
low-cardinality string values. Also verify the `ErrorKind` `Debug` output does
not include payload data before changing the representation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/superpowers/specs/2026-07-04-net-http-tracing-layer-design.md`:
- Around line 55-57: The spec still references the module as tracing.rs and pub
mod tracing, but the chosen module name is trace; update the references in the
design doc to trace.rs and pub mod trace; and make the same rename anywhere else
in the spec that still mentions tracing so the follow-up implementation matches
the actual module name.

---

Nitpick comments:
In `@crates/adapter/net/http/api/src/retry.rs`:
- Around line 246-259: The per-attempt `http.attempt` event in `retry.rs` is
using `?e.kind()` for `error_kind`, which is inconsistent with the stable label
convention used by `http.request` in `trace.rs`. Update the `tracing::event!`
call in the retry path to use the same `kind_label()` mapping for `ErrorKind`,
and make that helper `pub(crate)` in `trace.rs` so both telemetry surfaces emit
the same low-cardinality string values. Also verify the `ErrorKind` `Debug`
output does not include payload data before changing the representation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: d1abd15d-9c4f-43ff-bcdd-6c754774cd4e

📥 Commits

Reviewing files that changed from the base of the PR and between 68d8f60 and 7f1b1f4.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock, !**/*.lock
📒 Files selected for processing (9)
  • CHANGELOG.md
  • Cargo.toml
  • crates/adapter/net/http/api/Cargo.toml
  • crates/adapter/net/http/api/src/lib.rs
  • crates/adapter/net/http/api/src/retry.rs
  • crates/adapter/net/http/api/src/trace.rs
  • docs/adr/0034-http-construction-surface-auth-guarded-boot-coverage.md
  • docs/superpowers/plans/2026-07-04-net-http-tracing-layer.md
  • docs/superpowers/specs/2026-07-04-net-http-tracing-layer-design.md

Comment thread docs/superpowers/specs/2026-07-04-net-http-tracing-layer-design.md
NotAProfDev and others added 2 commits July 5, 2026 07:43
Address CodeRabbit review on #86:
- retry.rs's `http.attempt` event recorded `error_kind` via `?e.kind()`
  (Debug, e.g. `Connection`) while trace.rs's `http.request` span uses the
  stable low-cardinality `kind_label` (e.g. `connection`). Same telemetry
  field, two conventions — split downstream aggregation on the ADR-0014
  plane. Expose `kind_label` as `pub(crate)` and reuse it in retry.rs so both
  surfaces emit identical values. (ErrorKind is a fieldless enum — no payload,
  so this was consistency-only, not a secret-safety issue.)
- Design spec still referenced `tracing.rs`/`pub mod tracing;`; the shipped
  module is `trace`. Corrected the three stale references.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
# Conflicts:
#	CHANGELOG.md
#	docs/adr/0034-http-construction-surface-auth-guarded-boot-coverage.md
@NotAProfDev NotAProfDev merged commit 2c6e9b5 into main Jul 5, 2026
5 checks passed
@NotAProfDev NotAProfDev deleted the feat/net-http-tracing branch July 5, 2026 07:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(net): Tracing resilience layer (Slice 1, PR 5)

1 participant