Add --json flag that emits all results as a JSON array. Schema always uses min/avg/max per phase (consistent regardless of -n); phases absent from the request are omitted from the phases object. Output is buffered until all URLs complete, then printed as one pretty-printed array. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
106 lines
2.3 KiB
Markdown
106 lines
2.3 KiB
Markdown
# Step 4 — JSON Output
|
|
|
|
## What this step delivers
|
|
|
|
A `--json` flag that emits all results as a JSON array instead of the text
|
|
table. The text format remains the default.
|
|
|
|
The JSON schema is always the aggregate shape (min/avg/max per phase), even
|
|
for a single sample — so the schema is stable regardless of `-n`.
|
|
|
|
Phases absent from the request (e.g. TLS for `http://`) are omitted from the
|
|
`phases` object.
|
|
|
|
## Build
|
|
|
|
```sh
|
|
cd go
|
|
go build -o latprobe .
|
|
```
|
|
|
|
## Usage
|
|
|
|
```sh
|
|
latprobe --json [other flags] <url> [url ...]
|
|
```
|
|
|
|
## JSON Schema
|
|
|
|
```json
|
|
[
|
|
{
|
|
"url": "https://example.com",
|
|
"status": 200,
|
|
"samples": 1,
|
|
"phases": {
|
|
"dns": { "min_ms": 17.17, "avg_ms": 17.17, "max_ms": 17.17 },
|
|
"connect": { "min_ms": 12.01, "avg_ms": 12.01, "max_ms": 12.01 },
|
|
"tls": { "min_ms": 22.78, "avg_ms": 22.78, "max_ms": 22.78 },
|
|
"ttfb": { "min_ms": 12.99, "avg_ms": 12.99, "max_ms": 12.99 },
|
|
"transfer": { "min_ms": 0.18, "avg_ms": 0.18, "max_ms": 0.18 },
|
|
"total": { "min_ms": 66.19, "avg_ms": 66.19, "max_ms": 66.19 }
|
|
}
|
|
}
|
|
]
|
|
```
|
|
|
|
Phase keys: `dns`, `connect`, `tls` (HTTPS only), `ttfb`, `transfer`, `total`.
|
|
All `*_ms` values are floating-point milliseconds.
|
|
|
|
## Examples
|
|
|
|
### Single URL, single sample
|
|
|
|
```sh
|
|
$ ./latprobe --json https://example.com
|
|
[
|
|
{
|
|
"url": "https://example.com",
|
|
"status": 200,
|
|
"samples": 1,
|
|
"phases": { ... }
|
|
}
|
|
]
|
|
```
|
|
|
|
### Multiple samples — min/avg/max diverge
|
|
|
|
```sh
|
|
$ ./latprobe --json -n 5 https://example.com
|
|
[
|
|
{
|
|
"url": "https://example.com",
|
|
"status": 200,
|
|
"samples": 5,
|
|
"phases": {
|
|
"total": { "min_ms": 45.00, "avg_ms": 52.30, "max_ms": 61.80 },
|
|
...
|
|
}
|
|
}
|
|
]
|
|
```
|
|
|
|
### Pipe to jq
|
|
|
|
```sh
|
|
# Extract avg total latency for each URL
|
|
$ ./latprobe --json -n 3 https://example.com https://www.google.com \
|
|
| jq '.[] | {url, avg_total_ms: .phases.total.avg_ms}'
|
|
|
|
{
|
|
"url": "https://example.com",
|
|
"avg_total_ms": 52.3
|
|
}
|
|
{
|
|
"url": "https://www.google.com",
|
|
"avg_total_ms": 82.8
|
|
}
|
|
```
|
|
|
|
## Notes
|
|
|
|
- Output is buffered until all URLs are measured, then printed as one array.
|
|
Errors for individual URLs are written to stderr; that URL is excluded from
|
|
the JSON array, and the process exits with code 1.
|
|
- The text format is unchanged and remains the default (no `--json` flag).
|