feat: add per-user write byte statistics#27547
Merged
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds opt-in per-user write request byte accounting to the httpd service (mirroring existing per-user query response byte tracking), and fixes MaxBodySize enforcement for gzip-encoded write bodies by applying truncation after decompression.
Changes:
- Add per-user
userwritebytesstatistics (tagged by user, with unauthenticated attributed to(anonymous)), gated byuser-write-bytes-enabled. - Ensure per-user write counters are incremented at the same points as the global
writeReqBytescounter, preserving the “sum of per-user equals global” invariant. - Fix
MaxBodySizefor gzip requests by wrapping the decoded stream withtruncateReader, preventing decompression bombs from bypassing the limit; add extensive tests covering behavior and /debug/vars visibility.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| services/httpd/service.go | Adds the userWriteReqBytes value field constant for per-user write stats. |
| services/httpd/handler.go | Emits per-user userwritebytes stats and accounts write bytes per user; applies MaxBodySize after gzip decode. |
| services/httpd/handler_test.go | Adds comprehensive tests for per-user write byte accounting, gzip sizing behavior, concurrency, and /debug/vars exposure. |
| services/httpd/config.go | Introduces the user-write-bytes-enabled config flag. |
| etc/config.sample.toml | Documents the new user-write-bytes-enabled flag alongside the existing query counterpart. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
davidby-influx
marked this pull request as ready for review
July 17, 2026 16:16
Contributor
Author
Add a userwritebytes statistic, the write-path mirror of the shipped userquerybytes measurement, gated behind a new opt-in [http] user-write-bytes-enabled flag. When enabled, every v1, v2, and Prometheus remote write adds its request body bytes to a per-user counter, reported as one userwritebytes statistic per user, tagged with the user name, and visible through SHOW STATS and /debug/vars (admin-gated only when pprof-auth-enabled is set; otherwise /debug/vars is unauthenticated). Unauthenticated writes are attributed to "(anonymous)". Bytes are counted at the same sites that feed the aggregate writeReqBytes field of the httpd statistic, so the per-user values sum exactly to the global counter. Behavior is unchanged by default. The counters inherit the existing writeReqBytes units: /write counts post-gzip decompressed bytes while the Prometheus endpoint counts compressed wire bytes, and tests pin both so changing that inconsistency becomes a conscious decision. New tests cover the sum invariant, anonymous attribution, concurrent writes under the race detector, early-error paths that must count nothing, and /debug/vars visibility under both pprof-auth modes (admin-gated and the unauthenticated default). The test harness gains a WriteAuthorizer mock, previously declared but never wired, making authenticated write paths testable for the first time. The per-user statistic emission in Handler.Statistics is extracted into a helper shared with userquerybytes, and both flags are now documented in the sample config. This also fixes a pre-existing gap where gzip request bodies bypassed the MaxBodySize limit: truncateReader now wraps the decompressed stream, so an oversized gzip body is rejected with 413 rather than buffered in full.
davidby-influx
force-pushed
the
DSB/write_stats
branch
from
July 20, 2026 18:31
a4c5431 to
7eecb17
Compare
Contributor
Author
|
rebased |
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.
Add a userwritebytes statistic, the write-path mirror of the shipped userquerybytes measurement, gated behind a new opt-in [http] user-write-bytes-enabled flag. When enabled, every v1, v2, and Prometheus remote write adds its request body bytes to a per-user counter, reported as one userwritebytes statistic per user, tagged with the user name, and visible through SHOW STATS and /debug/vars (admin-gated only when pprof-auth-enabled is set; otherwise /debug/vars is unauthenticated). Unauthenticated writes are attributed to "(anonymous)". Bytes are counted at the same sites that feed the aggregate writeReqBytes field of the httpd statistic, so the per-user values sum exactly to the global counter. Behavior is unchanged by default.
The counters inherit the existing writeReqBytes units: /write counts post-gzip decompressed bytes while the Prometheus endpoint counts compressed wire bytes, and tests pin both so changing that inconsistency becomes a conscious decision. New tests cover the sum invariant, anonymous attribution, concurrent writes under the race detector, early-error paths that must count nothing, and /debug/vars visibility under both pprof-auth modes (admin-gated and the unauthenticated default). The test harness gains a WriteAuthorizer mock, previously declared but never wired, making authenticated write paths testable for the first time. The per-user statistic emission in Handler.Statistics is extracted into a helper shared with userquerybytes, and both flags are now documented in the sample config.
This also fixes a pre-existing gap where gzip request bodies bypassed the MaxBodySize limit: truncateReader now wraps the decompressed stream, so an oversized gzip body is rejected with 413 rather than buffered in full.