Repository navigation
build-telemetry: finalize pending history traces, raise the job-wide payload cap, and report export caps in the lifecycle - #135
Merged
Conversation
…aces buildkitd writes a build's trace attachment asynchronously, keeping the span recorder open for up to 3s after the record completes. A job whose last build finished just before the post step therefore exported that record without a trace descriptor and then pruned it, so the row landed with trace_missing=1 and no steps. Before collecting, completed records that lack a trace descriptor are finalized via UpdateBuildHistory(Finalize: true), which blocks until the trace is attached (no-op for already-finalized records). Fail-soft with a 5s timeout per record. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Contributor
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
piob-io
marked this pull request as ready for review
September 4, 2026 16:20
ajwerner
approved these changes
Sep 4, 2026
The 8 MiB cap predates chunked reporting, when it was the bound on a single ReportDockerBuild request. With ~3 MiB chunks the per-request size is already controlled, so the job-wide cap only decides how many builds of a many-build job keep their traces; at 8 MiB roughly a dozen builds with ~1 MiB traces fit and the rest ship truncated. 32 MiB lets such jobs ship whole while still bounding teardown. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…cycle Every cap that can silently shrink the telemetry is now accounted for in DockerJobLifecycle so absent traces and unattributed builds can be explained from ClickHouse instead of runner debug logs: - timeline_bytes / timeline_truncated: runner step-timeline bytes actually shipped and whether the 1 MiB tail cap cut off the head. - history_export_bytes: record + trace bytes exported across all chunks. - traces_dropped_oversize: traces omitted for a per-build reason (over the per-trace cap or content-store read failure). - traces_dropped_payload_cap / records_dropped_payload_cap: traces, or whole records, omitted because the job-wide 32 MiB cap was reached. Admission to the job-wide cap is factored into admitBuild so the counters are disjoint (a whole-record drop is never also counted as a trace drop) and unit-testable; counters are copied onto the lifecycle only once the export completes, so a timed-out export leaves them at zero. Bumps @buf/blacksmith_vm-agent.bufbuild_es to the BSR commit that carries the new fields. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@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.
Summary
Three follow-ups to the post-step history export from #128, each a self-contained commit: builds no longer lose their trace to buildkitd's asynchronous trace finalization, the job-wide payload cap is sized for the chunked reporting that #128 introduced, and every cap that can shrink the telemetry is reported in the job lifecycle so gaps are explainable from ClickHouse.
Finalize pending history records before exporting traces
buildkitd attaches a build's OTLP trace to its history record asynchronously: after emitting the
COMPLETEevent it keeps the span recorder open for up to 3s (waiting for a finalizer or the timer) before writing the trace blob to the content store and stampingrecord.trace. A post step that starts right after the lastdocker buildlists a completed record withtrace == undefined, ships it without a trace, and then prunes it — the row lands indocker_build_summarywithtrace_missing=1and an emptystepsarray. In an end-to-end lab run this hit the final build of most multi-build jobs and every single-build job that ended just before teardown (69 of 205 rows).exportBuildHistoryruns a pre-pass before collection:UpdateBuildHistory{Finalize:true}triggers the record's finalizer and blocks until the trace is written (no-op for records already finalized), so the collection pass sees the descriptor. Finalize failures/timeouts are logged at debug and the record is still exported (without trace). A lab rerun with this change went from 69/205 to 0/185trace_missingrows.Job-wide history payload cap: 32 MiB
MAX_TOTAL_PAYLOAD_BYTESbounds record + trace bytes for the whole job. At 8 MiB it was the single-request bound from before chunked reporting; with ~3 MiBReportDockerBuildchunks the per-request size is already controlled, so the job-wide cap only decides how many builds of a many-build job keep their traces — at 8 MiB roughly a dozen builds with ~1 MiB traces fit and the rest shiptruncatedwith no steps. 32 MiB lets such jobs ship whole while still bounding teardown. The per-record (512 KiB), per-trace (2 MiB), per-request (~3 MiB) and timeline (1 MiB) caps and the 15s export timeout are unchanged.Export caps and timeline size reported in
DockerJobLifecycleUntil now the only evidence that a cap fired was a
core.debugline in the runner log. The lifecycle (sent in the first report chunk only) now carries:timeline_bytes/timeline_truncatedhistory_export_bytestraces_dropped_oversizetraces_dropped_payload_captruncated=1)records_dropped_payload_capJob-wide admission is factored into
admitBuild(build, traceUnavailable, counters)so the three drop counters are disjoint — a build lands in at most one, whole-record drops taking precedence — and unit-tested. Counters accumulate during collection and are copied onto the lifecycle only when the export completes, so a timed-out export (which ships no builds) reports zeros alongsidehistory_export_timed_out.readRunnerStepTimeline(lifecycle)records the shipped size/truncation viacapRunnerStepTimeline.Requires
@buf/blacksmith_vm-agent.bufbuild_es2.14.1-20260904184135-ab292bb91e69.3(fields added agent-side in FastActions/fa#5449; columns in useblacksmith/web#12482). Agents that predate the fields ignore them; the row still inserts with the columns at their defaults.dist/is rebuilt.Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled. (Staging)Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.Link to Devin session: https://app.devin.ai/sessions/0c6ebc2a6de54933bebe821e21ab8b76
Open in Devin Desktop: https://app.devin.ai/desktop/session/0c6ebc2a6de54933bebe821e21ab8b76?variant=devin
Requested by: @piob-io