Skip to content

johnneerdael/wiretrail

Repository files navigation

wiretrail

CI Crates.io License

wiretrail is a fast, deterministic, agent-friendly HAR (HTTP Archive) analyzer for the command line. It answers narrow, repeatable questions about a network capture in a single command — storms, duplicates, retries, errors, auth flows, slow calls, what varies between repeated requests, ranked root-cause diagnosis, body search/extraction, and regression diff against a baseline — with structured terminal output and a stable --json schema, and no GUI.

It is HeapTrail for network captures. It reuses heaptrail's design philosophy: agentic/LLM-driven investigation, deterministic output that diffs cleanly, JSON for machine consumers, and fixed single-command answers instead of an interactive load-and-explore session.

Forked from mandrean/har-rs, which contributes the HAR 1.2/1.3 struct definitions; this fork replaces the parse path with an mmap single-pass loader and adds the analysis CLI documented below.

Motivation

Each log.entries[] item in a HAR already exposes the request, response, content, timings, cache metadata, headers, cookies, URL, method, status, and bodies — more than enough to reconstruct the kind of manual "what happened during this capture?" analysis a debugger does by hand. wiretrail turns that into single-command answers.

Sanitization is treated as core, not optional: HARs routinely contain cookies, auth headers, tokens, request/response bodies, and user data. wiretrail redacts by default across every output — including secret-bearing blobs hidden in URL path segments — and only reveals raw values with an explicit --unsafe-include-secrets flag.

When to use wiretrail

  • Agentic / LLM-driven investigation. Structured terminal output (with --json) lets an agent run a command, read the result, and decide the next probe. Every command prints a "next useful commands" footer.
  • Headless / CI. Single static binary, deterministic output, defined exit codes (0 clean, 1 findings, 2 invalid HAR). compare --fail-on <severity> turns a regression diff against a baseline HAR into a strict pass/fail gate.
  • Large captures. mmap single-pass parse: a 143 MB capture (2237 entries) loads in ~0.5 s using ~2× the file size in RAM.
  • Safe to share. Redact-by-default makes report, curl, and show-entry output safe to paste into a ticket; --unsafe-include-secrets when you actually need to replay a call.
  • Narrow, repeatable questions. "What are the request storms?", "Which calls are wasteful duplicates vs retries?", "What's the auth/refresh story?", "What differs between these 27 identical-looking POSTs?" — one command each.

When to use browser DevTools / a proxy GUI

  • Live, interactive inspection while reproducing a flow — Chrome DevTools, Charles, Proxyman, HTTP Toolkit stay in their column.
  • Editing and re-sending requests interactively. wiretrail emits sanitized curl for replay but isn't an interactive client.

The tools complement each other: capture in a proxy/DevTools, then run wiretrail over the exported .har for fast, scriptable, agent-friendly post-mortem analysis.

Install

cargo install wiretrail

Or build from git:

git clone https://github.com/johnneerdael/wiretrail
cd wiretrail
cargo build --release   # ./target/release/wiretrail

Pre-built binaries for Linux/macOS/Windows are attached to each GitHub release.

Usage

wiretrail <FILE> [COMMAND] [OPTIONS]

<FILE> is a HAR (1.2 or 1.3) export. With no command, summary runs.

wiretrail capture.har                      # executive summary (default)
wiretrail capture.har auto                 # smart one-shot: summary + auto-drill the findings
wiretrail capture.har duplicates           # repeated calls, grouped
wiretrail capture.har errors --json        # 4xx/5xx grouped, as JSON
wiretrail capture.har show-entry e000123   # full redacted detail for one entry
wiretrail capture.har curl e000123 --unsafe-include-secrets  # replayable cURL

Start with auto for an unfamiliar capture: it prints the summary, ranks the likely problems, and inlines the relevant deeper analysis (errors, retries, auth, …) scoped to exactly where the trouble is — one command, no guessing what to run next. summary itself now ends with a ranked recommended next steps section, so even the default command tells you precisely which follow-ups matter.

Global options

Option Effect
--json Emit the stable JSON envelope instead of terminal text.
--top N Bound list sizes (default 10).
--filter "<expr>" Restrict to matching entries (repeatable).
--config <path> Path to wiretrail.yaml (default: ./wiretrail.yaml if present).
--unsafe-include-secrets Show raw auth headers, tokens, bodies, and URL secrets instead of redacting.

The filter language: host:api.foo.com status:>=400 method:POST path:*login* time:>1000ms has:req.header.authorization.

Commands

Overview & inventory

Command Answers
summary (default) Capture meta, time range, status/resource breakdown, top hosts, top duplicates, slowest, biggest payloads, root-cause hints.
hosts Per-host: count, methods, status distribution, p50/p95/max latency, bytes, time window, duplicate count.
subsystems Group hosts into named integrations (built-in vendor heuristics + wiretrail.yaml ownership map).
endpoints Normalized endpoint inventory (host, method, {id} path, statuses, content types, sample query keys).
timeline Chronological per-request view with DUP/RETRY markers.

Wasteful traffic

Command Answers
duplicates Repeated method + normalized-path + query fingerprint, grouped; marks retries.
retries Repeats that follow a failed attempt (5xx/429/network), with backoff gaps.
storms Bursts of many calls to one host/endpoint within a window (--window-ms, --min-count).
pagination Pagination loops + N+1 fan-out (--max-pages, --fanout-min, --window-ms).
rate-limit 429 events, Retry-After, X-RateLimit-*, cooldown violations.

Failures & timing

Command Answers
errors 4xx/5xx grouped by endpoint+status, with parsed message/code, correlation IDs, body snippet.
redirects Redirect chains/storms, cross-host hops.
transitions Status sequences: 401→200, 429→429, 5xx→2xx.
slowest Top-N slow calls with timing-phase breakdown + bottleneck classifier.

Auth

Command Answers
jwt Find and decode JWTs (header/claims, exp/skew) — hashed sub, never the signature or raw token by default.
auth 401/403 patterns, inconsistent auth, token rotation, and token-refresh flows (old-token-reuse, concurrent, failed).
handoff Backend trace-handoff blocks for failed + slowest requests (template, correlation IDs, server IP, sanitized cURL).

Inspection, diff & export

Command Answers
show-entry <id> Full normalized request/response/timings for one entry, redacted.
diff What varies across repeated calls to one endpoint (query/header/body verdict: identical / volatile-only / meaningful).
search <pattern> Grep request/response bodies (--regex, --ignore-case); redaction-safe context snippets.
extract <jsonpath> Pull a JSON-path value from bodies ($.errors[0].code, [*] wildcard); --target req|resp; opaque values masked.
export Flatten entries to NDJSON or CSV (--format ndjson|csv) — metadata only, no raw bodies.
report A dossier-style markdown report composed from the analyses.
curl [id] Sanitized, safety-labeled curl replay for one entry or all filtered entries.

Diagnosis & quality

Command Answers
auto Smart one-shot: prints the summary, then drills the top-ranked recommendations (HIGH+MED by default) inline, each scoped by its own filter. --all / --min-severity widen/narrow.
diagnose Ranked root-cause findings synthesized from all analyses (severity-sorted, with evidence IDs + a suggested follow-up command).
validate Capture quality + analysis sufficiency (timings/bodies/auth coverage, sanitized?, anomalies).
startup Boot/startup profile: max concurrency, critical path, slow dependencies (--window-ms).
cascade Earliest failure and the downstream failures it triggered (--window-ms, --min-downstream).

Regression & rules

Command Answers
compare <baseline.har> Diff this capture against a baseline: new/removed hosts & endpoints, new errors, latency regressions, payload growth — severity-scored. --fail-on <severity> gates CI.
rules Evaluate wiretrail.yaml rules + built-in packs (--pack auth,caching,payments,security,rest,graphql).

Run wiretrail <file> <command> --help for per-command options.

Example

$ wiretrail capture.har summary
== wiretrail summary ==
entries: 2237 total, 2237 after filter
duration (first start to last response): 1354.1s

status classes:
  2xx: 2040
  4xx: 57
  5xx: 2

top hosts (by request count):
    785  api.themoviedb.org
    131  yjyuomfgkqwmjvnoxurn.supabase.co

top duplicate calls:
    29x  POST youtubei.googleapis.com /youtubei/v1/visitor_id ...

hints:
  - 29x duplicate calls: POST youtubei.googleapis.com /youtubei/v1/visitor_id ...
  - 59 error responses (4xx/5xx/failed)

next useful commands: duplicates · errors · slowest

Configuration

An optional wiretrail.yaml (in the working directory, or via --config) maps hosts/paths to named subsystems and declares required-header rules:

ownership:
  - name: Payments API
    host: "payments.*.foo.com"
    owner: payments-team
    criticality: high

required_headers:
  - host: "api.foo.com"
    headers: ["Authorization", "X-App-Version", "Accept"]

rules:
  - name: "API calls need auth"
    host: "api.foo.com"          # globs; optional method/path/status matchers
    require_headers: ["Authorization"]
    max_latency_ms: 2000
  - name: "no staging hosts in prod capture"
    host: "*.staging.foo.com"
    forbid: true                 # any match is a violation

rules evaluates this list plus any built-in --packs; subsystems falls back to built-in vendor heuristics then raw host when no ownership rule matches.

Redaction & safety

Every command redacts by default: auth/cookie headers, sensitive query params, JSON body keys (password/token/secret/…), JWT signatures, and opaque secret-bearing blobs embedded in URL path segments (collapsed to {blob} in aggregate views, <redacted> in show-entry/curl). Pass --unsafe-include-secrets to reveal raw values for replay. curl labels each command SAFE/UNSAFE based on method and payment/order keywords.

Performance

mmap + a single typed serde_json::from_slice over the mapped bytes — no intermediate serde_json::Value DOM. Measured on a 143 MB capture (2237 entries): parse + summary in ~0.5 s, ~314 MB peak RSS (~2.2× file size). Every command runs in well under a second on that input. Release builds use lto = "fat".

Format support

  • HAR 1.2 and 1.3 (parsed through a unified permissive model; unknown fields ignored).
  • Reads JSON HAR exports from Chrome/Edge DevTools, Charles, Proxyman, HTTP Toolkit, mitmproxy, and others.

Known limitations

HAR cannot prove low-level packet loss, full TLS certificate chains, client call stacks, or proxy/service-worker internals unless captured in custom fields. JWT analysis is structural only (no signature verification). N+1 detection is a best-effort heuristic. See USERGUIDE.md for details and worked examples.

Claude Code plugin

This repo ships a Claude Code plugin that teaches the assistant to drive wiretrail. It auto-triggers on "analyse/debug HAR", "wiretrail", or a .har file in the conversation, and adds an /analysing-har slash command.

# One-time: add the marketplace
/plugin marketplace add johnneerdael/wiretrail

# Install the plugin
/plugin install analysing-har@analysing-har

# Use it
/analysing-har path/to/capture.har
# …or just say "analyse this HAR" / "debug this HAR" and the skill triggers.

The plugin wraps the wiretrail CLI (auto-installs via cargo install wiretrail if missing) and follows the triage workflow in USERGUIDE.md.

License

MIT. See LICENSE.

About

wiretrail is a fast, deterministic, agent-friendly HAR (HTTP Archive) analyzer for the command line.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages