8700fbfae1
- backend + gateway multi-stage distroless Dockerfiles; the gateway embeds and
serves the SPA at / and /telegram/ via go:embed (committed dist placeholder,
real build baked in by the image's node stage)
- deploy/docker-compose.yml: backend + gateway + Postgres + Telegram connector
(VPN sidecar) + OTel Collector + Prometheus (15d) + Tempo (72h) + Grafana,
fronted by a caddy owning a single /_gm Basic-Auth (admin console + Grafana
subpath); inter-service on a private network, only caddy on the edge network
- new metrics: backend accounts_created_total{kind} (robots excluded) and an
in-memory gateway active_users{window=24h,7d} gauge
- CI: single .gitea/workflows/ci.yaml (unit/integration/ui + a gated test-contour
deploy) on the new feature/* -> development -> master branch model; the old
go-unit/integration/ui-test workflows are folded in; the connector-scoped
compose is retired (superseded by deploy/)
- docs: ARCHITECTURE §11/§12/§13, root + gateway READMEs, CLAUDE.md branching,
PLAN.md (stage 16 done + refinements + Stage 17 forward-notes)
59 lines
2.5 KiB
JSON
59 lines
2.5 KiB
JSON
{
|
|
"uid": "scrabble-overview",
|
|
"title": "Scrabble — Service overview",
|
|
"tags": ["scrabble"],
|
|
"timezone": "",
|
|
"schemaVersion": 39,
|
|
"version": 1,
|
|
"refresh": "30s",
|
|
"time": { "from": "now-6h", "to": "now" },
|
|
"panels": [
|
|
{
|
|
"type": "stat",
|
|
"title": "Active users (24h)",
|
|
"gridPos": { "h": 5, "w": 6, "x": 0, "y": 0 },
|
|
"datasource": { "type": "prometheus", "uid": "prometheus" },
|
|
"targets": [{ "refId": "A", "expr": "max(active_users{window=\"24h\"})" }]
|
|
},
|
|
{
|
|
"type": "stat",
|
|
"title": "Active users (7d)",
|
|
"gridPos": { "h": 5, "w": 6, "x": 6, "y": 0 },
|
|
"datasource": { "type": "prometheus", "uid": "prometheus" },
|
|
"targets": [{ "refId": "A", "expr": "max(active_users{window=\"7d\"})" }]
|
|
},
|
|
{
|
|
"type": "stat",
|
|
"title": "Edge requests/s",
|
|
"gridPos": { "h": 5, "w": 6, "x": 12, "y": 0 },
|
|
"datasource": { "type": "prometheus", "uid": "prometheus" },
|
|
"targets": [{ "refId": "A", "expr": "sum(rate(edge_request_duration_count[5m]))" }]
|
|
},
|
|
{
|
|
"type": "stat",
|
|
"title": "Edge error ratio",
|
|
"gridPos": { "h": 5, "w": 6, "x": 18, "y": 0 },
|
|
"fieldConfig": { "defaults": { "unit": "percentunit" }, "overrides": [] },
|
|
"datasource": { "type": "prometheus", "uid": "prometheus" },
|
|
"targets": [{ "refId": "A", "expr": "sum(rate(edge_request_duration_count{result!=\"ok\"}[5m])) / clamp_min(sum(rate(edge_request_duration_count[5m])), 1)" }]
|
|
},
|
|
{
|
|
"type": "timeseries",
|
|
"title": "Goroutines by service",
|
|
"description": "OTel Go runtime metric; verify the exact name against live Prometheus if empty (go_goroutine_count / process_runtime_go_goroutines depending on the contrib runtime version).",
|
|
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 5 },
|
|
"datasource": { "type": "prometheus", "uid": "prometheus" },
|
|
"targets": [{ "refId": "A", "expr": "go_goroutine_count", "legendFormat": "{{service_name}}" }]
|
|
},
|
|
{
|
|
"type": "timeseries",
|
|
"title": "Heap memory used by service",
|
|
"description": "OTel Go runtime metric (best-effort name go_memory_used); verify against live Prometheus if empty.",
|
|
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 5 },
|
|
"fieldConfig": { "defaults": { "unit": "bytes" }, "overrides": [] },
|
|
"datasource": { "type": "prometheus", "uid": "prometheus" },
|
|
"targets": [{ "refId": "A", "expr": "sum(go_memory_used) by (service_name)", "legendFormat": "{{service_name}}" }]
|
|
}
|
|
]
|
|
}
|