d2a9441287
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 13s
CI / ui (pull_request) Successful in 49s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m7s
Follow-ups on the honest-AI game, same PR: - GCG export labels the robot seat "AI" instead of its pool name (ExportGCG overrides via accounts.IsRobot); the in-app 🤖 is unchanged. - vs_ai games emit no your_turn (the robot replies instantly, so it would be redundant); opponent_moved still advances the UI. - Admin console shows the AI flag: a 🤖 column in /games and an "AI game" line on the game card (GameRow/GameDetailView gain VsAI). - games_started_total / games_abandoned_total gain a vs_ai attribute; the Grafana Game-domain dashboard splits started/abandoned into human and AI panels. Tests: metrics unit (vs_ai split); integration (no your_turn, GCG "AI").
82 lines
3.9 KiB
JSON
82 lines
3.9 KiB
JSON
{
|
|
"uid": "scrabble-game",
|
|
"title": "Scrabble — Game domain",
|
|
"tags": ["scrabble"],
|
|
"timezone": "",
|
|
"schemaVersion": 39,
|
|
"version": 3,
|
|
"refresh": "30s",
|
|
"time": { "from": "now-24h", "to": "now" },
|
|
"panels": [
|
|
{
|
|
"type": "timeseries",
|
|
"title": "Games started / abandoned — human (rate by variant)",
|
|
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 0 },
|
|
"datasource": { "type": "prometheus", "uid": "prometheus" },
|
|
"targets": [
|
|
{ "refId": "A", "expr": "sum(rate(games_started_total{vs_ai=\"false\"}[15m])) by (variant)", "legendFormat": "started {{variant}}" },
|
|
{ "refId": "B", "expr": "sum(rate(games_abandoned_total{vs_ai=\"false\"}[15m])) by (variant)", "legendFormat": "abandoned {{variant}}" }
|
|
]
|
|
},
|
|
{
|
|
"type": "timeseries",
|
|
"title": "Games started / abandoned — AI (rate by variant)",
|
|
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 0 },
|
|
"datasource": { "type": "prometheus", "uid": "prometheus" },
|
|
"targets": [
|
|
{ "refId": "A", "expr": "sum(rate(games_started_total{vs_ai=\"true\"}[15m])) by (variant)", "legendFormat": "started {{variant}}" },
|
|
{ "refId": "B", "expr": "sum(rate(games_abandoned_total{vs_ai=\"true\"}[15m])) by (variant)", "legendFormat": "abandoned {{variant}}" }
|
|
]
|
|
},
|
|
{
|
|
"type": "timeseries",
|
|
"title": "Robot games finished (rate)",
|
|
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 24 },
|
|
"datasource": { "type": "prometheus", "uid": "prometheus" },
|
|
"targets": [{ "refId": "A", "expr": "sum(rate(robot_games_finished_total[15m]))", "legendFormat": "robot games" }]
|
|
},
|
|
{
|
|
"type": "timeseries",
|
|
"title": "Live games in cache (by variant)",
|
|
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 8 },
|
|
"datasource": { "type": "prometheus", "uid": "prometheus" },
|
|
"targets": [{ "refId": "A", "expr": "sum(game_cache_active) by (variant)", "legendFormat": "{{variant}}" }]
|
|
},
|
|
{
|
|
"type": "timeseries",
|
|
"title": "Chat messages (rate by kind)",
|
|
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 8 },
|
|
"datasource": { "type": "prometheus", "uid": "prometheus" },
|
|
"targets": [{ "refId": "A", "expr": "sum(rate(chat_messages_total[15m])) by (kind)", "legendFormat": "{{kind}}" }]
|
|
},
|
|
{
|
|
"type": "timeseries",
|
|
"title": "Journal replay p95 (by variant)",
|
|
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 16 },
|
|
"fieldConfig": { "defaults": { "unit": "s" }, "overrides": [] },
|
|
"datasource": { "type": "prometheus", "uid": "prometheus" },
|
|
"targets": [{ "refId": "A", "expr": "histogram_quantile(0.95, sum(rate(game_replay_duration_bucket[5m])) by (le, variant))", "legendFormat": "{{variant}}" }]
|
|
},
|
|
{
|
|
"type": "timeseries",
|
|
"title": "Move validate p95 (by variant)",
|
|
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 16 },
|
|
"fieldConfig": { "defaults": { "unit": "s" }, "overrides": [] },
|
|
"datasource": { "type": "prometheus", "uid": "prometheus" },
|
|
"targets": [{ "refId": "A", "expr": "histogram_quantile(0.95, sum(rate(game_move_validate_duration_bucket[5m])) by (le, variant))", "legendFormat": "{{variant}}" }]
|
|
},
|
|
{
|
|
"type": "timeseries",
|
|
"title": "Move think-time by phase (p50 / p95)",
|
|
"description": "Seconds a seat spent on a committed move, by game phase. Aggregates all seats including robots; per-human analysis is in the admin console.",
|
|
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 24 },
|
|
"fieldConfig": { "defaults": { "unit": "s" }, "overrides": [] },
|
|
"datasource": { "type": "prometheus", "uid": "prometheus" },
|
|
"targets": [
|
|
{ "refId": "A", "expr": "histogram_quantile(0.5, sum(rate(game_move_duration_bucket[15m])) by (le, phase))", "legendFormat": "p50 {{phase}}" },
|
|
{ "refId": "B", "expr": "histogram_quantile(0.95, sum(rate(game_move_duration_bucket[15m])) by (le, phase))", "legendFormat": "p95 {{phase}}" }
|
|
]
|
|
}
|
|
]
|
|
}
|