Skip to content

feat(slo): let an SLI attach labels only it can supply - #14

Open
chris13524 wants to merge 1 commit into
mainfrom
feat/slo-decorate-hook
Open

chris13524 wants to merge 1 commit into
mainfrom
feat/slo-decorate-hook

Conversation

@chris13524

Copy link
Copy Markdown
Member

What

labelled(sli, expr) now applies an SLI's optional decorate(expr) outermost, after all the burn arithmetic. Guarded with std.objectHasAll, so an SLI that doesn't define it takes exactly the previous code path.

Why outermost

This is the point of the change, not an implementation detail.

PromQL binary ops match on the full label set. A label added to bad but not to the budget built from events therefore produces no series at all — a silently empty rule, not an error. Outermost is the only placement where a decoration cannot break the arithmetic it decorates.

It also applies the decoration once per rule instead of once per window. These expressions are already near the size where AMG's PutAlertRuleGroup gets flaky, so a per-window copy of a 31-entry label map would be expensive.

Relationship to #13

Complementary, not overlapping — I checked before writing this.

blockchain-api uses the pair together: its per-chain SLIs aggregate by (chain_id), decorate maps each id to the human chain name from chain_config.json, and dimension_template then renders Avalanche C-Chain (eip155:43114) rather than the CAIP-2 id alone. Companion PR in blockchain-api.

Backwards compatibility — verified, not assumed

Both consumers were rendered with and without the change:

consumer result
pay-core promtool suite 8/8 SUCCESS, unchanged
pay-core rendered alerts.jsonnet byte-identical, 466,564 bytes each way
blockchain-api promtool suites 2/2 SUCCESS

🤖 Generated with Claude Code

`labelled(sli, expr)` now applies an SLI's optional `decorate(expr)` outermost,
after all the burn arithmetic. Optional and guarded, so an SLI that does not
define it takes exactly the previous code path.

The placement is the point, not an implementation detail. PromQL binary ops match
on the full label set, so a label added to `bad` but not to the budget built from
`events` yields no series at all — a silently empty rule rather than an error.
Wrapping at the end also applies it once per rule instead of once per window,
which matters because these expressions are already near the size where Amazon
Managed Grafana's rule-group writes get flaky.

Complements #13 rather than overlapping it. That PR gave the caller
`dimension_template` to PRINT a dimension label; this gives an SLI a way to
CREATE one. blockchain-api uses the pair together: its per-chain SLIs aggregate
`by (chain_id)`, `decorate` maps each id to the human chain name from
chain_config.json, and `dimension_template` renders "Avalanche C-Chain
(eip155:43114)" instead of the CAIP-2 id alone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant