fix(perf-harness): close 4 gaps from Phase 2.11B deployment perf run - #249
Merged
Merged
Conversation
- measure-baseline.py: update gateway metric names from collector v0.108 to v0.141. - docs/phase-2-perf-deployment.md: document backend /metrics gap as design-level (separate concern from harness fixes). - asap-precompute-go: add per-observation Prom histogram in runtime; shim wiring for at least DDSketch. - baseline-b3-delta.yml: bump load profile to saturating workload for CPU regression discrimination.
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
Closes the four harness gaps surfaced by Phase 2.11B (PR #238) so the
next operator running the deployment-perf audit gets real numbers in
every column instead of NaN, and so a 10% shim regression is visible
at the CPU level rather than buried in measurement noise.
Per-gap status
deploy/scripts/measure-baseline.py/metricsempty under ingest-only soakdocs/phase-2-perf-deployment.md"Gaps" #2asap-precompute-go/precompute.go,ddsketchprocessor/{monitor,processor,config_translate,shim_helpers}.godeploy/docker-compose/baseline-b3-delta.ymlGap 1 — gateway metric names
Each gateway query is now
<v0.141 name> or <v0.108 name>:otelcol_process_cpu_seconds_total or otelcol_process_cpu_seconds,otelcol_process_memory_rss_bytes or otelcol_process_memory_rss,and the analogous
_total/no-suffix pair onotelcol_receiver_accepted_metric_pointsandotelcol_exporter_sent_metric_points. Today's stack (v0.141 on bothagent and gateway) populates the first variant; legacy worktree
replays still hit the second. NaN only when neither exists.
Gap 2 — backend /metrics
asap_ingest_samples_totalandasap_query_duration_seconds_bucketgenuinely don't exist under ingest-only operation; closing the gap
needs either a PromQL replay path on the harness side or a synthetic
ingest counter on the backend. Both are out of scope for a
harness-fixes PR. Doc updated to call this out plus a docstring note
on the query templates themselves so the operator sees in-script why
the column is blank.
Gap 3 — per-observation latency histogram
Two-part fix:
asap-precompute-go). Adds aLatencyObserver func(d time.Duration)hook installed viaPrecompute.SetLatencyObserver.The hook fires once per
Observecall (success, ErrSeriesCapExceeded,ErrLateData, matcher-miss all count) so the histogram envelope
matches what
testing.Bmeasured in Phase 2.11A. Stored in anatomic pointer so concurrent Observe calls see a coherent snapshot;
hot-path cost when nil is one Load + nil-check.
enableSelfMonitoringconstructs aFloat64Histogramnamedasap_processor_observe_secondswithbucket boundaries spanning 50 ns – 10 ms. Each per-metric
Precompute spawned via
getOrCreatepicks up the histogram viaproc.recordObserveLatency. Surfaces on the deployed/metricsendpoint when
EnableSelfMonitoring=true(production default).The other 4 shims (KLL, HLL, CountSketch, CountMin) stay backwards-
compatible — they don't call
SetLatencyObserverand lose nothing.Wiring those four is mechanical; deferred to Phase 2.11C to keep
this PR focused per the task scope constraint.
Test:
TestPrecompute_LatencyObserverinprecompute_test.goexercises hook installation, fires-once-per-Observe semantics
(including post-Tick), and disable.
Gap 4 — saturating workload
baseline-b3-delta.ymlnow overridesEXPORTER_CARDINALITY=100000and
EXPORTER_FREQ_HZ=100(both still env-shadowable), chosen toland the agent in the 50–70% one-core band on the reference
Threadripper hardware. Numerical re-baselining of pre-shim vs
post-shim under the new profile is not in this PR — that's its
own measurement, tracked as Phase 2.11C "saturating-load
comparison".
Validation
-racealso passes on the new test (atomic-pointer LatencyObserverslot exercised under concurrent Observe).
Test plan
go test ./...clean inasap-precompute-gogo test ./...clean in all 5 shim processorsgo test -v ./...clean inintegration/paritypython3 -c "import py_compile; py_compile.compile('deploy/scripts/measure-baseline.py')"cleanyaml.safe_load(open('deploy/docker-compose/baseline-b3-delta.yml'))cleanrecord numbers in a Phase 2.11C doc — out of scope for this PR
(harness-fixes only)
HLL, CountSketch, CountMin) — Phase 2.11C follow-up
Follow-ups (deferred)
shims (mechanical copy of the DDSketch monitor.go diff).
agent CPU under the saturating workload.
asap_sketch_payload_bytes_per_windowcounter (gap KLL Aggregator Implementation #4in the doc, untouched here — separate metric design).
EXPORTER_RATEreference inrun-baseline-sweep.sh(gap KLL in otel-client #5 in the doc, untouched)./metricspopulatesunder ingest+query soak (gap CountMinSketch in opentelemetry-collector #2 design-level concern).
🤖 Generated with Claude Code