Classify network failures (dns/connect/timeout/tls) with distinct exit codes 2-5. Add --timeout (default 10s) via context.WithTimeout. Add --fail for exit 6 on HTTP status >= 400. Preserve partial phase timing up to the failure point. -n sampling continues on network failures, aggregating successes and reporting fail counts. JSON extended with succeeded/failed/errors fields. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
64 lines
2.5 KiB
Markdown
64 lines
2.5 KiB
Markdown
# Changelog
|
||
|
||
All completed features are logged here in reverse-chronological order.
|
||
|
||
---
|
||
|
||
## 2026-07-01 00:38 — Failure handling (Go, Step 5)
|
||
|
||
- Classified network failures into `dns` / `connect` / `timeout` / `tls` with distinct exit codes (2–5)
|
||
- Partial timing preserved up to the failure point (e.g. DNS phase shown on NXDOMAIN)
|
||
- `--timeout` flag (default 10s) applied via `context.WithTimeout`
|
||
- `--fail` flag: HTTP status ≥ 400 → exit code 6 (curl-style)
|
||
- `-n` sampling continues on network failure; aggregates successes, reports fail count + cause
|
||
- JSON output extended with `succeeded`, `failed`, `errors[]` fields
|
||
- Highest exit code across all URLs/failure types is used as the process exit
|
||
|
||
---
|
||
|
||
## 2026-07-01 00:08 — JSON output flag (Go, Step 4)
|
||
|
||
- `--json` flag emits a JSON array with one entry per URL
|
||
- Schema always uses min/avg/max shape (consistent regardless of `-n`)
|
||
- Phases absent from the request (e.g. TLS on HTTP) are omitted from the JSON object
|
||
- Failed URLs are excluded from JSON output and reported to stderr
|
||
- Text output unchanged and remains the default
|
||
|
||
---
|
||
|
||
## 2026-07-01 00:08 — Multiple URLs + sampling (Go, Step 3)
|
||
|
||
- `-n`/`--count` flag repeats each URL N times and reports min/avg/max per phase
|
||
- `probe.Summarize` aggregates a slice of Results into per-phase PhaseStats
|
||
- Multi-sample output shows an aligned min/avg/max table with a header row
|
||
- Single-sample output (n=1) is unchanged from Step 2
|
||
|
||
---
|
||
|
||
## 2026-07-01 00:08 — Per-phase breakdown (Go, Step 2)
|
||
|
||
- Instrumented requests with `net/http/httptrace.ClientTrace`
|
||
- DNS lookup, TCP connect, TLS handshake, Server/TTFB, Transfer, Total phases
|
||
- TLS row omitted automatically for plain `http://` URLs
|
||
- Aligned text output with separator before Total
|
||
|
||
---
|
||
|
||
## 2026-07-01 00:08 — Simple total latency (Go, Step 1)
|
||
|
||
- `probe.Measure` performs an HTTP GET and records wall-clock total time
|
||
- `main.go` prints URL, HTTP status code, and total duration for each URL
|
||
- Exits with code 1 if any URL fails
|
||
- Multiple URLs accepted as positional arguments
|
||
|
||
---
|
||
|
||
## 2026-07-01 00:08 — Project scaffold (Go, Step 0)
|
||
|
||
- Created project structure: `go/`, `python/`, `docs/plans/`, `docs/usage/`
|
||
- Initialised Go module `latprobe` (`go/go.mod`)
|
||
- Minimal `go/main.go` that prints usage and exits cleanly when no URL is given
|
||
- Stub `go/internal/probe/probe.go` defining the `Result` type and `Measure` signature
|
||
- Foundation files: `README.md`, `CLAUDE.md`, `CHANGELOG.md`
|
||
- Saved initial plan to `docs/plans/2026-07-01-00-08-go-latency-tool.md`
|