Restore per-transaction .csv.zst output via --full flag#475
Open
russfellows wants to merge 4 commits intominio:masterfrom
Open
Restore per-transaction .csv.zst output via --full flag#475russfellows wants to merge 4 commits intominio:masterfrom
russfellows wants to merge 4 commits intominio:masterfrom
Conversation
klauspost
reviewed
Apr 8, 2026
Collaborator
klauspost
left a comment
There was a problem hiding this comment.
Sure. It is overly dramatic, though - and lacks mentioning the main downside.
Author
|
Klaus,
I didn’t want to presume to own the warning messages to your clients coming from your code.
I am happy to craft the output messages, but being that you all own the product, I would think you would prefer to control the messages.
I will run some analysis of the memory usage and time issues you cited. I don’t find them to be of much concern, but you seem to feel they are. So, in order to provide fact based messages, I will run some analysis. If you already have data points you would rather output, that is of course up to you.
To be clear, this is just fixing a documented feature that was recently broken. A better solution all the way around would be to utilize histograms, such as HDR histograms to collect the metrics. That way you can combine the results from multiple clients accurately and maintain statistical accuracy of all data points such as mean, median, p90, p95, p99 values.
The current 5 second averaging method you use by default loses statistical validity. In contrast, the detailed zst trace log files you can collect, do provide statistically valid results, as you well know, but at the expense of processing time at the end.
Regards,
—Russ
… On Apr 16, 2026, at 8:47 AM, Klaus Post ***@***.***> wrote:
@klauspost commented on this pull request.
In README.md <#475 (comment)>:
> +using the `--benchdata` parameter.
+
+## Full Per-Transaction Logging (`--full`)
+
+Adding `--full` to any benchmark command enables full per-transaction logging. With this
+flag warp writes **both** output files:
+
+| File | Contents |
+|------|----------|
+| `<benchdata>.csv.zst` | Every individual request — one row per operation, [zstandard](https://facebook.github.io/zstd/)-compressed CSV/TSV |
+| `<benchdata>.json.zst` | Aggregated summary (same as default) |
+
+```bash
+warp put --host=... --full
+```
+
Then the issue just gets closed as not planned. If you want to take ownership of the fix, I am offering code review. That is it.
—
Reply to this email directly, view it on GitHub <#475 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AF64UJ2D5KZTJFKY2GCYJUD4WDW6PAVCNFSM6AAAAACXQBCJPGVHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHM2DCMRRHA2DONJQHA>.
You are receiving this because you authored the thread.
|
Prior to commit 483f844, warp wrote a per-transaction CSV/TSV file after every benchmark run. That commit introduced addCollector() but registered --full only in analyzeFlags, never in benchFlags, so the flag had no effect and the per-transaction file was never written. This commit restores the intended behavior: * addCollector() now gates on ctx.Bool("full"). Without --full, only a LiveCollector (aggregating only) is used and .json.zst is the sole output — same default behavior as pre-483f844. * With --full, ops are fanned to both a NewOpsCollector (capturing every individual request) and the LiveCollector (live display and auto-termination). After the benchmark, .csv.zst is written first, then .json.zst is also written — so --full is strictly additive; both files are always produced together. * benchserver.go (distributed mode) mirrors this: with --full it downloads raw ops, writes .csv.zst, then downloads the aggregate and writes .json.zst. Without --full it writes .json.zst only. * The --full flag already exists in analyzeFlags, which is combined with benchFlags for all benchmark commands. A duplicate --full registration in benchFlags that caused a startup panic has been removed. * warp analyze now prints a warning when a .csv.zst is analyzed without --full: re-aggregating ops into 1-second buckets loses per-operation resolution, producing results equivalent to reading the .json.zst. Users are directed to add --full for precise latency percentiles and throughput figures. The warning is suppressed when --quiet or --json output is active. * README updated with an "Analyzing Results" subsection documenting the difference between default and --full analysis paths, and noting that --full is silently ignored on .json.zst files (which contain no individual operations). * 7 unit tests added in cli/addcollector_test.go covering: default mode stores no ops, --full collects all ops, --full fans out to LiveCollector, default mode updates channel is functional, DiscardOutput suppresses both modes, --full is additive (both files written), and op value preservation.
…ad docs - cli/analyze.go: soften warning from 'WARNING:' to 'Note:'; remove trailing newline from Println arg (fixes govet) - cli/addcollector_test.go: fix misspell 'behaviour' -> 'behavior'; remove redundant embedded field selector b.Common.Collector -> b.Collector (fixes staticcheck QF1008) - README.md: replace vague memory/perf caution with measured data — table of RSS overhead at three concurrency/duration levels (~310 B/op at low load, ~850 B/op at high concurrency), explanation of Go GC arena growth, and analysis time comparison (csv.zst --full is ~5x slower than json.zst; re-aggregating without --full is ~13x slower)
e6b62e1 to
8f5a66f
Compare
Author
|
Thanks for the feedback. Pushed an updated commit that:
|
There was a problem hiding this comment.
Pull request overview
Restores the intended --full behavior for benchmarks so per-transaction .csv.zst output is produced again (alongside the aggregate .json.zst), and adds a user-facing warning when analyzing .csv.zst without --full.
Changes:
- Reworks collector wiring so
--fullcollects per-op data while preserving live aggregation for UI/autoterm. - Mirrors
--fullbehavior for remote benchmarks by downloading ops for.csv.zstand still writing.json.zst. - Adds an analyze-time warning for
.csv.zstwithout--full, plus new unit tests and README updates.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
cli/benchmark.go |
Wires --full to collect ops + keep live updates; writes .json.zst alongside .csv.zst in full mode. |
cli/benchserver.go |
In remote mode, downloads ops for .csv.zst when --full and also writes the aggregate .json.zst. |
cli/analyze.go |
Emits a warning when analyzing .csv.zst without --full (unless quiet/JSON). |
cli/addcollector_test.go |
Adds unit tests covering default/full/discard-output collector behavior. |
README.md |
Documents --full outputs and analysis behavior differences for .csv.zst vs .json.zst. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
bench: restore per-transaction
.csv.zstoutput via--fullflagSummary
Prior to commit
483f844,warpwrote a per-transaction CSV/TSV file after everybenchmark run, enabling fine-grained post-hoc analysis with
warp analyze. Thatcommit introduced
addCollector()but registered the--fullflag only inanalyzeFlags— never inbenchFlags— so the flag silently had no effect andthe per-transaction file was never written.
This PR restores the intended behavior with a minimal, targeted fix across three
files, adds unit tests, and updates documentation.
Problem
After
483f844, running any benchmark with--full:produced only a
.json.zstaggregate file. The.csv.zstper-transaction file wasnever written, making post-hoc per-operation analysis impossible. The flag appeared
to be accepted but was completely ignored.
Changes
cli/benchmark.go— Core fix (single-node mode)addCollector()now gates onctx.Bool("full"):--full(default): ALiveCollectoronly. Live throughput display andauto-termination work as before. Output:
.json.zstonly.--full: Ops are fanned to both aNewOpsCollector(capturing everyindividual request) and the
LiveCollector(for live display). After the benchmark,.csv.zstis written first, then.json.zstis also written.--fullis strictlyadditive — both files are always produced together.
A duplicate
--fullflag registration inbenchFlagsthat caused a startup panic(since
--fullalready lives inanalyzeFlags, which is combined withbenchFlagsfor all benchmark commands) has been removed.
cli/benchserver.go— Distributed mode mirror--full: Downloads raw ops → writes.csv.zst→ downloads aggregate →writes
.json.zst.--full: Downloads aggregate → writes.json.zstonly.cli/analyze.go— User-facing warningwarp analyze file.csv.zstwithout--fullre-aggregates individual operations into1-second buckets before reporting, producing results equivalent to reading the
.json.zstaggregate. This loses per-operation resolution — latency percentiles andthroughput figures can differ, and per-request filtering flags have no additional
effect.
A warning is now printed in this case:
The warning is suppressed when
--quietor--jsonoutput is active.cli/addcollector_test.go— New unit tests (7 tests)TestAddCollectorDefaultNoOpsTestAddCollectorFullCollectsOps--fullcaptures all operationsTestAddCollectorFullFansOutToLive--fullalso feeds the LiveCollectorTestAddCollectorDefaultUpdatesChannelTestAddCollectorDiscardOutputTestAddCollectorFullIsAdditive--fullalways produces both filesTestAddCollectorOpValuesREADME.md— DocumentationAdded an Analyzing Results subsection under Full Per-Transaction Logging
documenting:
warp analyze --full file.csv.zstfor accurate per-operation stats.csv.zstre-aggregates (same as.json.zst) and now warns--fullis silently ignored when analyzing.json.zstBehavior Before / After
warp put(no flags).json.zstwritten.json.zstwritten ✓warp put --full.json.zstwritten (bug).csv.zstand.json.zstwritten ✓warp analyze file.csv.zstwarp analyze --full file.csv.zstwarp analyze --full file.json.zstTesting
Validated against a real MinIO S3 cluster. With
--full:All 7 unit tests pass:
go test ./cli/ -run TestAddCollector -v