Signals' metrics by person and whose key paid (#278)

With the server paying for everyone's Signals, its bill had no names.
ipx_signals_judged_total, ipx_signals_hits_total and ipx_jev_tokens_total
now carry user (the account's name) and key (server or own); a call
shared on the server's key is split by each person's share of its
questions. Icon picks bill the person on the server's key, key checks on
their own. The dashboard has tokens and items by person and a Who used
what table over its range.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-17 15:26:50 +00:00
parent ce78599ab4
commit 4eba746ba4
8 changed files with 107 additions and 32 deletions

View File

@@ -291,6 +291,29 @@ p = ts("Against TypeSafe's limits", [prom('sum(rate(ipx_jev_requests_total{job="
p["fieldConfig"]["defaults"]["custom"]["thresholdsStyle"] = {"mode": "line"}
p["fieldConfig"]["defaults"]["thresholds"] = {"mode": "absolute", "steps": LIMIT(80)}
y += 8
# By person and whose key paid (#278): who the server's TypeSafe bill is for. An item shared on the
# server's key is split by each person's share of its questions.
ts("Input tokens by person", [prom('sum by (user, key) (increase(ipx_jev_tokens_total{job="ipx", kind="input"}[$__rate_interval]))',
legend="{{user}} ({{key}} key)")],
0, w=8, bars=True, stack=True, desc="server is the server's TypeSafe key, what the server pays for; own is the person's own key.")
ts("Items judged by person", [prom('sum by (user, key) (increase(ipx_signals_judged_total{job="ipx"}[$__rate_interval]))', legend="{{user}} ({{key}} key)"),
prom('sum by (user) (increase(ipx_signals_hits_total{job="ipx"}[$__rate_interval]))', ref="B", legend="{{user}}: fit a Signal")],
8, w=8, bars=True)
def ptab(expr, ref):
return {"refId": ref, "datasource": PROM, "expr": expr, "instant": True, "format": "table"}
panel("table", "Who used what", 8, 8, 16,
[ptab('sum by (user, key) (increase(ipx_jev_tokens_total{job="ipx", kind="input"}[$__range]))', "A"),
ptab('sum by (user, key) (increase(ipx_jev_tokens_total{job="ipx", kind="output"}[$__range]))', "B"),
ptab('sum by (user, key) (increase(ipx_signals_judged_total{job="ipx"}[$__range]))', "C")],
description="Over the dashboard's time range: each person's input and output tokens and items judged, and whose key paid. "
"Icon picks are on the server's key, key checks on the person's own.",
transformations=[{"id": "merge", "options": {}},
{"id": "organize", "options": {"excludeByName": {"Time": True},
"renameByName": {"user": "Person", "key": "Key", "Value #A": "Input tokens",
"Value #B": "Output tokens", "Value #C": "Items judged"}}}],
options={"showHeader": True, "sortBy": [{"displayName": "Input tokens", "desc": True}]},
fieldConfig={"defaults": {"decimals": 0}, "overrides": []})
y += 8
# ---- ipx: the process, what it holds between requests and jobs (#194)
row("ipx: process")