You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix: normalize label values once, when a label combination is first stored
Non-string label values bypassed escapeLabelValue() and could render
malformed exposition (#791). Escaping during metrics() costs linear in
total cardinality (#792/#793 were declined for that), so values are
coerced at the storage boundary instead, once per new combination.
- LabelMap gains one insertion point, #insert, used by set, setDelta,
getOrAdd and merge. The entry gets a copy the store owns, coerced
with the same ToString the exposition applies, so a caller mutating
its object afterwards cannot change what a stored series reports.
- normalizeLabels() walks with for...in, because keyFrom() reads
inherited enumerable labels too. Labels that no enumeration reaches,
or whose prototype chain intercepts writes, are unsupported. The copy
keeps the source prototype, so keyFrom() answers absent declared names
the way the source did.
Nullish values are copied as-is, and __proto__ needs
Object.defineProperty rather than assignment.
- merge() keeps the stored labels instead of overwriting them with the
caller's object. getOrAdd() hands the stored labels to init(), so
Summary's value holds that same object rather than the caller's, and
its export helpers are unchanged from main. LabelGrouper does not
normalize; the store-backed labels it receives are normalized already.
Benchmarks and the observable output changes are in the PR description.
Fixes#791
Signed-off-by: Changhyun Kim <milcho0604@gmail.com>
Copy file name to clipboardExpand all lines: CHANGELOG.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -16,6 +16,8 @@ project adheres to [Semantic Versioning](http://semver.org/).
16
16
- perf: Histogram rendering builds its export list straight from the store iterator instead of an intermediate array. Faster at high series counts on Node 24 and 26, can be slightly slower on Node 22
17
17
- fix: Correct content type exported for cluster and worker mode.
18
18
- perf: Remove truthy conditionals from default metric collectors
19
+
- fix: Non-nullish, non-string label values are coerced to strings when a combination is first stored, so exposition escapes them; the store also keeps its own copy, so mutating the caller's object after recording no longer changes the stored series
20
+
- fix: Label-less summaries report `labels: {}` in `getMetricsAsJSON()`, like other metrics
0 commit comments