mirror of
https://github.com/XRPLF/rippled.git
synced 2026-08-21 14:20:56 +00:00
fix(telemetry): park the span panels in their own row, tighten the site label
Four findings from a review pass over the PR. The "Spans & traces" row was empty. Moving the row header down to clear the back-fill panels was only half the change -- the seven span-derived panels stayed at their old y, one unit below the native panels, so every pair overlapped and Grafana parented all fifteen to "Back-fill & persistence". The panels now sit below the row header, which restores the split the runbook already describes: eight native panels answer "how much", seven span-derived ones answer "which". Both rows stay expanded, so the docs no longer call them collapsed. metric_constants() excises each namespaced block before the flat prefix pass. The flat pass classifies by identifier prefix and is meant for headers that name the role in the identifier because they have no `namespace metric`/`label`/`lval`; it was running over the whole header, so a `kLabel`-prefixed constant written inside `namespace metric` landed in both buckets and an instrument name became a valid label key for Rule D. Nothing in the tree does that today, which is why it went unnoticed, and why the guard is a test rather than a fix for an observed failure. The `site` label now keeps a non-default port and drops userinfo residue from the host. Omitting the port unconditionally merged two local sites that differ only by port; printing it unconditionally would have renamed the existing `https://vl.ripple.com` series. Comparing against the scheme default distinguishes a configured port from the one the Resource constructor fills in. parseUrl's host group also permits '@', so a malformed URI with two of them leaves part of the userinfo in `domain`.
This commit is contained in:
10
.github/scripts/otel-naming/check_otel_naming.py
vendored
10
.github/scripts/otel-naming/check_otel_naming.py
vendored
@@ -966,6 +966,7 @@ def metric_constants(root: Path) -> Tuple[Set[str], Set[str], Set[str]]:
|
||||
values: Set[str] = set()
|
||||
for h in find_metricname_headers(root):
|
||||
text = strip_comments(read_source(h))
|
||||
flat = text
|
||||
for ns, bucket in (
|
||||
("metric", names),
|
||||
("label", keys),
|
||||
@@ -974,9 +975,16 @@ def metric_constants(root: Path) -> Tuple[Set[str], Set[str], Set[str]]:
|
||||
for block in namespace_spans(text, ns):
|
||||
for m in METRIC_CONST_DEF.finditer(block):
|
||||
bucket.add(m.group(2))
|
||||
# Remove the block before the flat pass below, so the
|
||||
# enclosing namespace stays the only thing that decides a
|
||||
# namespaced constant's bucket. Without this, a `kLabel`-style
|
||||
# identifier written inside `namespace metric` lands in both
|
||||
# `names` and `keys`, and an instrument name silently becomes
|
||||
# an allowed label key for Rule D.
|
||||
flat = flat.replace(block, "", 1)
|
||||
# Flat style: classify by identifier prefix. Only constants outside the
|
||||
# namespaced blocks reach here, so a namespaced header is unaffected.
|
||||
for m in METRIC_CONST_DEF.finditer(text):
|
||||
for m in METRIC_CONST_DEF.finditer(flat):
|
||||
ident, value = m.group(1), m.group(2)
|
||||
if ident.startswith("kLabel"):
|
||||
keys.add(value)
|
||||
|
||||
@@ -1041,6 +1041,37 @@ class MetricConstantExtraction(unittest.TestCase):
|
||||
finally:
|
||||
shutil.rmtree(d)
|
||||
|
||||
def test_namespaced_constant_ignores_its_flat_prefix(self):
|
||||
# A `kLabel`-prefixed identifier written inside `namespace metric` must
|
||||
# be an instrument name only. The flat prefix pass exists for headers
|
||||
# that have no such namespace, so it must not also claim this one:
|
||||
# letting it through would make an instrument name a valid label key,
|
||||
# and Rule D would then accept `label_peer_total` as a label.
|
||||
names, keys, vals = self._run(
|
||||
_metric_header(
|
||||
metric_body=_mc("kLabelPeerTotal", "label_peer_total"),
|
||||
label_body=_mc("outcome", "outcome"),
|
||||
)
|
||||
)
|
||||
self.assertEqual(names, {"label_peer_total"})
|
||||
self.assertEqual(keys, {"outcome"})
|
||||
self.assertEqual(vals, set())
|
||||
|
||||
def test_flat_prefix_still_read_when_namespaces_absent(self):
|
||||
# The counterpart to the test above: with no `namespace metric`/`label`
|
||||
# block to excise, the flat pass must still classify by prefix.
|
||||
names, keys, vals = self._run(
|
||||
"#pragma once\n"
|
||||
"namespace xrpl::telemetry {\n"
|
||||
+ _mc("kLabelOutcome", "outcome")
|
||||
+ "\n"
|
||||
+ _mc("kResultResolved", "resolved")
|
||||
+ "\n}\n"
|
||||
)
|
||||
self.assertEqual(names, set())
|
||||
self.assertEqual(keys, {"outcome"})
|
||||
self.assertEqual(vals, {"resolved"})
|
||||
|
||||
|
||||
class RuleIMetricLiterals(unittest.TestCase):
|
||||
"""Rule I: literal instrument names / label keys at a metric emit site are
|
||||
|
||||
Reference in New Issue
Block a user