Files
ottyl/tickets/022-metrics-counters-rethink.md
T

2.8 KiB

022 — Metrics rethink: counters as the primitive, histograms/gauges derived

Summary

The wishlist calls for rethinking the metrics model: everything a metric declares should fundamentally be a counter (an occurrence at a point in time, optionally labeled). Histograms and gauges are not separate declaration kinds — they're derived views computed from counter data (bucketing counter events into histogram buckets; reducing counter series into a gauge-style "current value"). This changes how MetricDeclaration/BucketValue are modeled and how the already-shipped PromQL-style query support (promql.rs) evaluates rate()/sum()/histogram/gauge-shaped queries.

Scope

  • Re-express metric declarations as counter declarations: a match increments a counter for the resolved label set at the matched timestamp. This is close to today's BucketValue{values: Vec<(Sequence, Timestamp, MetricPrimitive)>} — audit whether the existing bucket representation already is this, or whether captured non-counter values (e.g. a captured Number used as a gauge reading today) need to be reinterpreted as counter increments plus a separately-derived gauge. Document the resulting semantics clearly since this is a model change to code that already exists and has callers (engine.rs, promql.rs, Metrics.tsx, Dashboards.tsx).
  • Histogram derivation: given a counter's events over a time range, bucket them (fixed-width or user-specified boundaries) and expose bucket counts — likely as a new PromQL-evaluable form (e.g. histogram(metric_name[param])) or a query option, consumed the same way existing series are.
  • Gauge derivation: given a counter's events, derive a "last value" / "value at time T" series from the most recent matching counter event — likely as another derived query form (e.g. gauge(metric_name[param])), rather than a distinct declaration/storage kind.
  • Update promql.rs's evaluator to support these derived forms without breaking existing raw counter queries.
  • Update Metrics.tsx's declaration form/help text and Dashboards.tsx's panel config if the query surface changes.

Acceptance criteria

  • A declared metric behaves as a counter: each match is an increment/event, not an arbitrary overwritten value.
  • A histogram-derived query against a counter with several distinct captured values buckets them correctly across a seeded fixture.
  • A gauge-derived query against a counter returns the most-recent value at a given point in the selected time range.
  • Existing raw counter queries (sum/rate over a plain counter, as today) continue to work unchanged.

Depends on

None — this is a rework of the already-shipped metric/bucket/PromQL code, not new foundational work. 023, 025 build on the resulting model.