feat(prometheus): fold state sets on the target page; forget series an endpoint drops (#5689)
#5689 "Prometheus target page: fold state sets, show epoch times, size bytes", step 1 of milestone 508 "Prometheus widget templates". - A state set (name ending in _state, a state label, every series 0 or 1; or the OpenMetrics form, the label named after the metric) reads as one row per thing it describes, naming the current state, the others on hover. fabledarchives_jobs{state} is a count and stays as it is. - label_pairs / state_label / fold_states in service.py, for the widget templates to reuse. - After a good scrape, series it no longer has lose their newest value (forget_gone): Archives' old build_info row read as current beside the new one. History stays; a failed scrape forgets nothing; alert rules keep their own last-sample time. - Epoch times and _bytes sizes were already read by shown_value / metric_value. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -20,8 +20,8 @@ from steward.models.users import UserRole
|
||||
|
||||
from .models import PrometheusTarget
|
||||
from .scraper import ScrapeError, scrape
|
||||
from .service import (OWN_METRICS, SOURCE, FormError, form_values, map_families, parse_form,
|
||||
patterns, target_state)
|
||||
from .service import (OWN_METRICS, SOURCE, FormError, fold_states, form_values, map_families,
|
||||
parse_form, patterns, target_state)
|
||||
|
||||
prometheus_bp = Blueprint("prometheus", __name__, template_folder="templates")
|
||||
|
||||
@@ -256,7 +256,9 @@ async def test_target():
|
||||
|
||||
def group_series(target_name: str, latest: list) -> list[dict]:
|
||||
"""The target's stored series grouped by metric, each with its rows:
|
||||
the labels that tell them apart, and the newest value."""
|
||||
the labels that tell them apart, and the newest value. A state set is
|
||||
folded to one row per thing it describes, naming the current state
|
||||
(`states` set on the group)."""
|
||||
groups: dict[str, list] = {}
|
||||
for row in latest:
|
||||
if row.resource_name == target_name and row.metric_name in OWN_METRICS:
|
||||
@@ -264,9 +266,18 @@ def group_series(target_name: str, latest: list) -> list[dict]:
|
||||
labels = row.resource_name[len(target_name) + 1:] if row.resource_name != target_name else ""
|
||||
groups.setdefault(row.metric_name, []).append({
|
||||
"labels": labels, "resource": row.resource_name, "at": row.recorded_at,
|
||||
**shown_value(row.metric_name, row.value)})
|
||||
return [{"metric": m, "rows": sorted(rows, key=lambda r: r["labels"])}
|
||||
for m, rows in sorted(groups.items())]
|
||||
"value": row.value, **shown_value(row.metric_name, row.value)})
|
||||
out = []
|
||||
for metric, rows in sorted(groups.items()):
|
||||
folded = fold_states(metric, rows)
|
||||
if folded is not None:
|
||||
out.append({"metric": metric, "states": True, "rows": [
|
||||
{"labels": f["labels"], "resource": f["resource"], "moment": None,
|
||||
"text": f["state"] or "none", "states": f["states"]} for f in folded]})
|
||||
else:
|
||||
out.append({"metric": metric, "states": False,
|
||||
"rows": sorted(rows, key=lambda r: r["labels"])})
|
||||
return out
|
||||
|
||||
|
||||
@prometheus_bp.get("/targets/<target_id>")
|
||||
|
||||
Reference in New Issue
Block a user