feat(go.d): chart histogram buckets as range heatmaps - #23013
Conversation
There was a problem hiding this comment.
Pull request overview
This PR changes Go metrix histogram bucket flattening from cumulative buckets to non-overlapping per-range bucket totals, and updates chartengine (both autogen and template-driven paths) to render histogram bucket charts as heatmaps.
Changes:
- Update
metrix.ReadFlatten()histogram bucket emission to output per-range bucket totals (including+Inf = count - last_finite_bucket). - Force histogram
_bucketcharts toheatmapinchartengine(planner + autogen) even if templates specify a different chart type. - Refresh tests and documentation to reflect range-bucket semantics and heatmap rendering.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/go/plugin/go.d/collector/prometheus/writer_test.go | Updates Prometheus writer expectations for range buckets and explicit +Inf. |
| src/go/plugin/go.d/collector/prometheus/testdata/golden/histogram.json | Adjusts golden output for new +Inf value and heatmap type. |
| src/go/plugin/go.d/collector/prometheus/collector_test.go | Updates histogram assertions to match range-bucket +Inf semantics. |
| src/go/plugin/framework/charttpl/README.md | Documents forced heatmap type for histogram bucket charts and non-cumulative bucket values. |
| src/go/plugin/framework/chartengine/README.md | Documents heatmap rendering and range-bucket semantics for histogram buckets. |
| src/go/plugin/framework/chartengine/planner.go | Forces histogram bucket charts to heatmap during plan construction (template + autogen). |
| src/go/plugin/framework/chartengine/planner_test.go | Extends planner tests to assert heatmap type for histogram bucket charts. |
| src/go/plugin/framework/chartengine/autogen.go | Switches histogram bucket autogen chart type to heatmap. |
| src/go/plugin/framework/chartengine/autogen_test.go | Adds assertion that histogram bucket autogen route uses heatmap chart type. |
| src/go/pkg/metrix/runtime_store_test.go | Updates runtime histogram flatten expectations for range buckets. |
| src/go/pkg/metrix/README.md | Documents range-bucket flattening and +Inf derivation; clarifies typed Histogram reads remain cumulative. |
| src/go/pkg/metrix/reader.go | Implements range-bucket flattening by differencing cumulative buckets and deriving +Inf. |
| src/go/pkg/metrix/host_scope_test.go | Updates scoped histogram flatten expectation for range buckets. |
| src/go/pkg/metrix/histogram_store_test.go | Updates existing histogram tests and adds coverage for “no finite bounds” => all count in +Inf. |
| .agents/skills/project-writing-go-modules-framework-v2/SKILL.md | Updates contributor guidance: avoid collector-local bucket workarounds; rely on heatmap + range buckets. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
No issues found across 15 files
Confidence score: 5/5
- Automated review surfaced no issues in the provided summaries.
- No files require special attention.
Architecture diagram
sequenceDiagram
participant Prom as Prometheus Collector
participant Store as CollectorStore (metrix)
participant Reader as ReadFlatten()
participant Engine as chartengine Planner
participant Template as charttpl Template
participant Dashboard
Note over Prom,Dashboard: Histogram Bucket Flow – Range Heatmap
Prom->>Store: Observe histogram points (cumulative buckets + count + sum)
Store->>Store: Store cumulative bucket cumulatives per commit cycle
alt When ReadFlatten() is called
Store->>Reader: ReadFlatten()
Reader->>Reader: Compute non-overlapping range bucket totals
Note over Reader: For each finite bound le[i]:<br/>bucketValue = cumulative[i] - cumulative[i-1]<br/>(first bucket is <= le[0])
Note over Reader: For +Inf bound:<br/>bucketValue = count - last finite cumulative
Reader-->>Prom: Return flattened series with range bucket values + count + sum
end
Note over Prom,Engine: Planner consumes flattened series
Prom->>Engine: Feed flattened read snapshot
Engine->>Engine: scanPlanSeries() iterates all series
Engine->>Engine: isHistogramBucketSeries() checks meta.SourceKind==Histogram and FlattenRole==HistogramBucket
alt Histogram bucket series detected
Engine->>Engine: forceHistogramBucketChartType() -> sets chartType to heatmap
end
Engine->>Engine: accumulateRoute() applies chart meta overrides
alt Series is histogram bucket
Engine->>Engine: Enforce cs.meta.Type = ChartTypeHeatmap
end
Engine-->>Prom: Plan with heatmap charts
Note over Prom,Template: Template-driven path (charttpl)
Template->>Engine: Template defines type: stacked or omitted
Engine->>Engine: Template type overridden to heatmap for _bucket series
Engine-->>Dashboard: Emit heatmap chart with incremental-algo bucket dimensions
Note over Dashboard: Heatmap rendering – le label is upper bound dimension key
There was a problem hiding this comment.
1 issue found across 8 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
|



Summary
Test Plan
Additional Information
For users: How does this change affect me?
Summary by cubic
Histogram bucket metrics are flattened into non-overlapping range totals and rendered as heatmaps by
chartengine(autogen and templates), with buckets ordered numerically and+Inflast. This replaces cumulative buckets and removes collector-local workarounds.New Features
metrix.ReadFlatten()emits range bucket totals;+Infiscount - last finite bucket. TypedHistogram()reads remain cumulative.chartengineforces_bucketseries toheatmapand keepsalgorithm: incremental;leremains the upper-bound label. Planner orders bucket dimensions numerically with+Inflast, applies this in inference and lifecycle, and sorts histogram dims after other dynamic dims when mixed.metrix,chartengine, andgo.d/prometheus.Migration
+Infrange bucket.Written for commit 98d06e2. Summary will update on new commits.