Skip to content

fix: repair observability dashboard data (tokens 0, errors 0, KPI decimals) - #85

Merged
DominikPinsel merged 4 commits into
mainfrom
fix/observability-dashboard-data
Aug 12, 2026
Merged

fix: repair observability dashboard data (tokens 0, errors 0, KPI decimals)#85
DominikPinsel merged 4 commits into
mainfrom
fix/observability-dashboard-data

Conversation

@DominikPinsel

@DominikPinsel DominikPinsel commented Aug 12, 2026

Copy link
Copy Markdown
Owner

The observability dashboard showed three symptoms; this PR fixes the distinct root causes behind them.

Symptoms → root causes

1. Tokens always 0

agent_tokens_used_total never existed in Prometheus: the chart ships default-deny-ingress and a PodMonitor for agent pods, but no ingress policy ever allowed scrapes to reach agent pods. All six agent scrape targets were down (up == 0) while the metrics servers themselves served data fine on localhost. Broken since the netpol posture shipped (2026-08-03).

Fix: new chart policy agent-metrics — ingress on the named metrics port for pods selected by managed-by: agent-operator (same selector as the PodMonitor, per the stable-selector guidance in docs/network-policies.md), matching the open-scraping posture of the hub-backend metrics rule. Verified in-cluster: after applying the policy, all agent targets flipped to up == 1 and /api/v1/tokens returns real data again (57M+ input tokens).

2. Errors always 0

Two compounding issues:

  • The runner never reported errors to the hub: failures only went to the pod console (logError) plus a nack. The errors feed reads task_logs with level=error, which had 228 info rows and 0 error rows. Fix: the runner now posts an error-level task log alongside every nack.
  • The Errors KPI card read hub_routing_errors_total — a counter that only increments on router failures, effectively always zero — so it would have stayed 0 anyway. Fix: with a range set, the card now counts error-level task logs in the window (the same entries the errors page lists); the counter remains the source for the legacy range-less path and when no log store is configured.

3. Events/Triggers cards showing many decimal places

With a range selected (the dashboard always sends one, default 24h), getMetricsSummary switches to sum(increase(...)), and increase() extrapolates fractional values (e.g. 64.7826). The KPI cards rendered those verbatim.

Fix: round each summary value (math.Round) before returning — these are event counts. New regression test covers fractional inputs.

Verification

  • go test ./... in services/hub — all packages pass (incl. new TestObservability_SummaryWithRangeRoundsFractionalCounts)
  • helm template renders the new policy correctly
  • runner extension: npm test — 83/83 pass
  • In-cluster (dev): applied agent-metrics manually → all agent scrape targets up, token usage flowing via the hub API

Note for deploy: the dev cluster already has an agent-metrics policy applied manually (with Helm-adoption annotations), so the next helm upgrade adopts it without conflict. Incident logged in AInsel/ainsel-deployment#15.

The summary endpoint switches to increase() queries when a range is
selected so the KPI cards show windowed counts. increase() extrapolates
fractional values (e.g. 64.7826), which the observability dashboard
rendered verbatim — the Events/Triggers cards showed long decimals
instead of counts. Round each summary value to the nearest integer
before returning; the metrics are event counts, so nothing is lost.
The chart ships a PodMonitor for agent pods, but under the default-deny
ingress policy no NetworkPolicy allowed scrapes to reach them: every
agent metrics endpoint silently refused connections, so
agent_tokens_used_total never landed in Prometheus and the dashboard
token counters stayed at 0.

Add an agent-metrics ingress policy selecting agent pods via
managed-by: agent-operator (same selector as the PodMonitor, so pods
predating the component label are covered) and opening the named
metrics port — the same open-scraping posture the hub-backend metrics
rule already uses.
Failed events were only logged to the pod's console (logError) and
nacked; nothing reached the hub's task_logs. The observability errors
feed reads task_logs with level=error, so it stayed empty even while
events were failing. Post an error-level task log alongside the nack so
failures surface in the hub errors view.
The Errors KPI card read hub_routing_errors_total, a counter that only
increments on router failures and was effectively always zero — so the
card stayed at 0 even while events failed and the errors page (which
lists error-level task logs) had entries. With a range set, report the
count of error-level task logs in the window instead; the counter
remains the source for the legacy range-less path and when no log store
is configured.
@DominikPinsel
DominikPinsel merged commit d0faa91 into main Aug 12, 2026
6 checks passed
@DominikPinsel
DominikPinsel deleted the fix/observability-dashboard-data branch August 12, 2026 23:26
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