Skip to content

feat: app-usage Prometheus metrics + Grafana dashboard + Helm scrape#22

Merged
shimoncohen merged 7 commits into
mainfrom
feat/app-usage-metrics
Jul 22, 2026
Merged

feat: app-usage Prometheus metrics + Grafana dashboard + Helm scrape#22
shimoncohen merged 7 commits into
mainfrom
feat/app-usage-metrics

Conversation

@shimoncohen

Copy link
Copy Markdown
Contributor

Summary

Adds application-usage metrics to the SvelteKit (adapter-node) server, exposes them for Prometheus, and ships a Grafana dashboard.

  • Metrics registry (src/lib/server/metrics.ts): prom-client with default process/nodejs metrics plus three custom metrics — http_requests_total, http_request_duration_seconds (labels method/route/status_code) and demo_views_total (labels client/name). HMR double-registration guard.
  • handle hook (src/hooks.server.ts): serves GET /metrics (excluded from its own counter) and times/counts every other request, labeled by the templated route.id (bounded cardinality — never the raw URL).
  • Demo view counter: demo_views_total incremented in the demo route load, after the demo is validated, so bogus /demo/*/* paths can't create unbounded label series and failed S3 fetches don't count as views.
  • Helm scrape wiring: adds the MapColonies mclabels dependency subchart → renders prometheus.io/scrape|port|path annotations (port 8080, /metrics) and mapcolonies.io/* labels, gated on mclabels.prometheus.enabled.
  • Grafana dashboard: grafana/maps-playground-dashboard.json shipped as a sidecar-provisioned ConfigMap (gated on metrics.grafanaDashboard.enabled, configurable discovery label). Panels: request rate by route, p50/p95 latency, error ratio, top demos, process mem/cpu.
  • Central vitest-setup.ts guard so node-env test files share the global teardown, plus a test pinning the two dashboard JSON copies in sync.

Test Plan

  • npm test — 35 passing (8 files), incl. metrics registry, handle hook, demo-view counter, dashboard-sync.
  • npm run check — 0 errors.
  • helm lint helm clean; helm template helm renders scrape annotations when enabled, none when disabled; Grafana ConfigMap gated correctly.
  • Deploy to a cluster: confirm Prometheus scrapes /metrics and the dashboard auto-loads via the Grafana sidecar.

🤖 Generated with Claude Code

shimoncohen and others added 7 commits July 21, 2026 14:50
Node-environment test files (server-side metrics) share the global
afterEach teardown but lack jsdom's localStorage. Guard the clear()
centrally instead of shimming per-file.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Increment demo_views_total after resolving the demo, so bogus /demo/*/* paths
(SvelteKit runs page + layout load concurrently, so the layout 404 does not stop
the page load) can't create unbounded label series, and failed S3 fetches no
longer count as views. Add a test pinning the two grafana dashboard copies in sync.
@shimoncohen shimoncohen self-assigned this Jul 21, 2026
@shimoncohen

Copy link
Copy Markdown
Contributor Author

OCP smoke test (infra-dev) — scrape confirmed ✅

Built this branch (60f4ae5) and ran it as a throwaway release in infra-dev, then tore it down. From the live pod:

demo_views_total{client="OpenLayers",name="WMTS"} 5
http_requests_total{method="GET",route="/",status_code="307"} 5
http_requests_total{method="GET",route="/demo/[client]/[name]",status_code="200"} 5
http_request_duration_seconds_count{route="/demo/[client]/[name]",status_code="200"} 5
+ prom-client default metrics
  • /metrics serves valid Prometheus exposition; all three custom metrics present and incrementing under traffic.
  • route label is the templated route id (/demo/[client]/[name]), not the raw path — cardinality-safe as designed.
  • Pod carried the scrape annotations a prometheus.io/scrape scraper keys on (scrape: "true", port: "8080", path: "/metrics").
  • Cluster Prometheus itself is RBAC-forbidden to me, so real ingestion wasn't observed — confirmation is endpoint + annotations.

Side finding: this branch also fixes the current dev CrashLoopBackOff

The running playground-dev-playground (old image 0.0.1-4) is in CrashLoopBackOff — getDemoIndex throws Error: property description not allowed on the dev S3 index.json, so GET / 500s and the liveness probe kills it. On this branch's image the same route returned 200 in the smoke test, i.e. the newer code tolerates the description field. Merging + redeploying dev should clear that crashloop as a side effect.

@shimoncohen
shimoncohen merged commit 3728bc8 into main Jul 22, 2026
6 checks passed
@shimoncohen
shimoncohen deleted the feat/app-usage-metrics branch July 22, 2026 08:17
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