Summary
The Uptime stat card on the UI Home Page (/ui) is a hardcoded placeholder. It always renders 99.98% / "last 30 days" regardless of how long the server has actually been running.
crates/ui/src/lib.rs:1375:
// Not part of the resource-count read path — placeholder until the bulk
// export job-state and availability read paths are wired.
export_jobs: "13".to_string(),
export_jobs_queued: 1,
uptime_percent: "99.98".to_string(),
The card should be driven by real data from the Prometheus metrics API rather than a constant.
Current state
crates/ui/templates/pages/index.html:23-25 renders metrics.uptime_percent with the label card-uptime ("Uptime") and sub-label card-uptime-sub ("last 30 days") — see locales/{en,es,de}/main.ftl.
helios-observability already exposes:
crates/observability/src/uptime.rs — uptime_seconds(), process start-time tracking.
crates/observability/src/metrics.rs — GET /metrics Prometheus exposition; sets an uptime_seconds gauge on each render.
- So a process uptime metric exists (
uptime_seconds), but an availability percentage over a window (what the card currently claims) does not — that would require historical scrape data (a Prometheus server), not just the in-process gauge.
Scope of work
- Hook the Home Page Uptime card up to real metrics instead of the hardcoded string.
- Decide (and then implement) what the card actually shows:
- Option A (simplest, self-contained): show process uptime duration from
uptime_seconds (e.g. "3d 4h") and change the sub-label away from "last 30 days". This needs no external Prometheus server. Note crates/ui/src/i18n.rs already has a health-uptime string ("Uptime: {duration}") that may be reusable.
- Option B: query an external Prometheus for an availability percentage over a window (e.g.
avg_over_time(up{...}[30d])), keeping the "% / last 30 days" presentation. Requires configuration for the Prometheus base URL and a graceful "unavailable" state when it isn't configured.
- If a needed metric isn't available, implement it in
helios-observability and export it via /metrics.
- Handle the unavailable/unknown state in the UI (don't render a fabricated number).
- Update the affected locale strings in
locales/en|es|de/main.ftl if the sub-label changes.
- Add tests covering the new read path (
crates/ui Rust tests; Playwright if the rendered text changes).
Notes / constraints
/metrics is public and unauthenticated — per the comment in crates/observability/src/metrics.rs, tenant must never appear as a metric label. Don't add per-tenant data to satisfy this card.
uptime_seconds in a clustered deployment behind a load balancer reflects only the process that served the scrape (see the doc comment in crates/observability/src/uptime.rs) — worth calling out in the UI copy or the chosen approach.
- The sibling placeholders on the same card row (
export_jobs, export_jobs_queued) are out of scope here unless trivially covered.
Acceptance criteria
Summary
The Uptime stat card on the UI Home Page (
/ui) is a hardcoded placeholder. It always renders99.98%/ "last 30 days" regardless of how long the server has actually been running.crates/ui/src/lib.rs:1375:The card should be driven by real data from the Prometheus metrics API rather than a constant.
Current state
crates/ui/templates/pages/index.html:23-25rendersmetrics.uptime_percentwith the labelcard-uptime("Uptime") and sub-labelcard-uptime-sub("last 30 days") — seelocales/{en,es,de}/main.ftl.helios-observabilityalready exposes:crates/observability/src/uptime.rs—uptime_seconds(), process start-time tracking.crates/observability/src/metrics.rs—GET /metricsPrometheus exposition; sets anuptime_secondsgauge on each render.uptime_seconds), but an availability percentage over a window (what the card currently claims) does not — that would require historical scrape data (a Prometheus server), not just the in-process gauge.Scope of work
uptime_seconds(e.g. "3d 4h") and change the sub-label away from "last 30 days". This needs no external Prometheus server. Notecrates/ui/src/i18n.rsalready has ahealth-uptimestring ("Uptime: {duration}") that may be reusable.avg_over_time(up{...}[30d])), keeping the "% / last 30 days" presentation. Requires configuration for the Prometheus base URL and a graceful "unavailable" state when it isn't configured.helios-observabilityand export it via/metrics.locales/en|es|de/main.ftlif the sub-label changes.crates/uiRust tests; Playwright if the rendered text changes).Notes / constraints
/metricsis public and unauthenticated — per the comment incrates/observability/src/metrics.rs, tenant must never appear as a metric label. Don't add per-tenant data to satisfy this card.uptime_secondsin a clustered deployment behind a load balancer reflects only the process that served the scrape (see the doc comment incrates/observability/src/uptime.rs) — worth calling out in the UI copy or the chosen approach.export_jobs,export_jobs_queued) are out of scope here unless trivially covered.Acceptance criteria