Skip to content

schedstat: add --json flag#9

Merged
tbg merged 6 commits into
mainfrom
add-json-flag
May 8, 2026
Merged

schedstat: add --json flag#9
tbg merged 6 commits into
mainfrom
add-json-flag

Conversation

@tbg
Copy link
Copy Markdown
Collaborator

@tbg tbg commented May 8, 2026

Summary

  • Refactor analyze() to populate typed Report struct hierarchy. Each section gets a String() that reproduces legacy plaintext output verbatim. Existing golden tests pass byte-identical.
  • Add --json flag. Emits one JSON object per trace, NDJSON across multiple traces. Durations as raw nanoseconds. Disabled sections omitted.
  • --json + --sql rejected. With --keep-db, footer goes to stderr so stdout stays valid NDJSON.
  • Golden test coverage extended: each .bin trace now has both .txt and .json golden, regenerated together via go test -rewrite.

Two commits, reviewable independently:

  1. `0806e09` refactor (no behavior change)
  2. `79af59a` feat (--json flag)

Test plan

  • `go test ./...` passes (text + JSON goldens)
  • `schedstat --json testdata/*.bin | jq -c .trace_file` produces valid NDJSON
  • `schedstat --json --sql` rejected with error
  • manual: run on a fresh trace, eyeball JSON shape

tbg and others added 5 commits May 8, 2026 10:00
Convert the previously streaming print* functions into collect* functions
that populate a typed Report struct hierarchy. Each section type carries a
String() method that reproduces the legacy plaintext output verbatim, so
existing golden tests pass byte-identical.

The Report struct is the single source of truth for both the plaintext
view (today) and a future JSON view: section-level structs use
JSON-friendly types (raw nanoseconds, slices) and json struct tags so
encoding/json can serialize the whole report directly.

analyze() still streams text section-by-section as each collect* returns,
preserving intra-trace progress on early termination.

No user-visible behavior change.

Co-Authored-By: roachdev-claude <roachdev-claude-bot@cockroachlabs.com>
--json emits the same analysis as a JSON object, with all durations as raw
nanoseconds and disabled sections omitted. Multiple trace files produce
NDJSON (one object per line), so the output streams cleanly through `jq`.

The flag is rejected with --sql (interactive shell). With --keep-db the
"DuckDB file: ..." footer is redirected to stderr so stdout stays valid
NDJSON.

Golden test coverage extended: each .bin trace now has both a .txt and
.json golden file, regenerated together via `go test -rewrite`.

Co-Authored-By: roachdev-claude <roachdev-claude-bot@cockroachlabs.com>
Multi-trace runs now fan out across GOMAXPROCS/4 workers. Each file's
output is buffered in its own slot and emitted in input order via a
per-slot done channel: as soon as the next-in-line file finishes, its
output streams to stdout — no waiting for the whole batch.

--sql is incompatible with the buffered/parallel path (it ends in
syscall.Exec). Reject when combined with multiple files; single-file
--sql still runs sequentially through runOne.

printSchemaInfo replaced with schemaInfo (returns string) so footer text
goes through the per-file writer instead of os.Stdout directly.

Co-Authored-By: roachdev-claude <roachdev-claude-bot@cockroachlabs.com>
The previous parallel implementation ran the dispatcher and emitter on
the same goroutine: dispatcher first, emitter second. With a long file
list the dispatcher's `sem <-` blocks every time the in-flight count
hits the concurrency cap, so the emitter never starts until near the
end of the run — even file 0's output stays buffered for minutes.

Move the dispatch loop to its own goroutine so the emitter can begin
draining results[0] immediately, streaming each file in input order as
soon as it is ready.

Co-Authored-By: roachdev-claude <roachdev-claude-bot@cockroachlabs.com>
GOMAXPROCS/4 left CPU idle (~70%) on multi-trace runs. Default to full
GOMAXPROCS, and expose --concurrency for tuning (0 = GOMAXPROCS).

Co-Authored-By: roachdev-claude <roachdev-claude-bot@cockroachlabs.com>
@tbg tbg marked this pull request as ready for review May 8, 2026 09:02
CI on linux produced golden mismatches against the darwin-generated JSON
because float64 results from DuckDB aggregates differ at the ULP level
across platforms (e.g. p99_ns 1760564.48 vs 1760564.4800000002).

Fix:
- Store all duration-ns fields as int64. Truncation is invisible in the
  text output (fmtDuration formats microsecond+ values), and removes the
  cross-platform precision noise from JSON.
- Round GC latency comparison ratios to 6 decimals; the text view shows
  one decimal so the rounding is invisible there too.

Goldens regenerated; text output is unchanged.

Co-Authored-By: roachdev-claude <roachdev-claude-bot@cockroachlabs.com>
@tbg tbg merged commit 8a82d05 into main May 8, 2026
1 check passed
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.

1 participant