Skip to content

feat(selfhost): GPU + AI-provider observability (exporter, Prometheus, Grafana dashboard) #4367

Description

@JSONbored

Part of #4325. Sequence against #4330 (observability stack migration/reset decision) — don't build a new dashboard twice.

Context

The self-host GPU host has zero GPU metrics collection today — no exporter, nothing feeding Prometheus, and no Grafana dashboard among the existing set (claude-usage, codex-usage, github-prs, gittensory, maintainer-reviews, orb-ai-usage, resource-hub) is GPU-specific. Separately, there is no application-level latency metric for embed/vision AI provider calls at all — src/selfhost/metrics.ts's DEFAULT_METRIC_META has no ai_* histogram, and src/selfhost/ai.ts only calls incr() for a couple of counters, never observe(). Without that, a GPU dashboard can only show raw utilization/VRAM — not the thing that actually matters (is a request slow, is it failing).

Requirements

  • Exporter: add utkuozdemir/nvidia_gpu_exporter:1.3.2 (lightweight, shells to nvidia-smi via the NVIDIA Container Toolkit; DCGM is the wrong fit for a consumer/workstation-class GPU) as a new docker-compose.yml service, own --profile gpu, matching the ollama/postgres-exporter service style (<<: *default-logging, expose not ports).
  • Prometheus: new gpu scrape job in prometheus/prometheus.yml, matching the existing profile-conditional job pattern.
  • New application metric: add gittensory_ai_provider_request_duration_seconds (histogram) and gittensory_ai_provider_request_errors_total (counter) to src/selfhost/metrics.ts's DEFAULT_METRIC_META, labeled by provider and request_kind (the existing requestKind() helper in src/selfhost/ai.ts:1065 already classifies each call as "embedding" | "review" — extend it to also cover vision/advisory once those exist). Wrap the call site around withReviewSpan in ai.ts (~line 1086).
  • Grafana: new grafana/dashboards/gpu-metrics.json, auto-provisioned via the existing grafana/provisioning/dashboards/provider.yml file-provider convention. Panels: Summary row (utilization %, VRAM used/total, temp, power as stat panels) + AI request performance row (request rate, p50/p95/p99 latency via histogram_quantile, error rate — all keyed off the new metric above) + a GPU utilization/VRAM/temp/power timeseries row. Match the existing dashboards' JSON panel style (see resource-hub.json/claude-usage.json).

Deliverables

  • gpu-exporter service in docker-compose.yml, --profile gpu
  • Prometheus scrape job wired
  • New AI-provider latency histogram + error counter instrumented in src/selfhost/ai.ts, tested
  • grafana/dashboards/gpu-metrics.json provisioned and rendering real data
  • .env.example documents any new vars

Expected outcome

A durable, always-on view of GPU utilization/VRAM/temp alongside real AI-request latency and error rate — the baseline this project needs before any of the other GPU-optimization work (embedding cache, advisory routing, vision-verify) can be measured for real impact rather than one-off manual benchmarks.

Effort

M

Metadata

Metadata

Assignees

Labels

maintainer-onlyOwner-only work — yields no Gittensor points.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions