Branding: bulk rename across 50+ files (Go, JS, CSS, HTML, YAML, JSON, shell scripts). Fix Helm chart description and git repo URLs. Fix test helper taglines. Admin surface: strip 14 gutted tabs (providers, models, personas, roles, knowledge, memory, tasks, health, routing, capabilities, channels, dashboard, usage, stats). Collapse to 4 categories: People, Workflows, System, Monitoring. Settings surface: strip 11 gutted tabs (models, personas, providers, roles, knowledge, memory, usage, workflows, tasks, data, gitkeys). Keep: general, appearance, profile, teams, connections, notifications. Team-admin surface: strip 5 gutted tabs (personas, providers, knowledge, tasks, usage). Keep: members, groups, connections, workflows, settings, activity. Components: delete chat-pane/ (13 files, 1938 lines) and notes-pane/ (10 files, 2381 lines). main.go: remove stale Health.Prune maintenance goroutine. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
208 lines
6.6 KiB
JSON
208 lines
6.6 KiB
JSON
{
|
|
"__inputs": [
|
|
{
|
|
"name": "DS_PROMETHEUS",
|
|
"label": "Prometheus",
|
|
"description": "",
|
|
"type": "datasource",
|
|
"pluginId": "prometheus",
|
|
"pluginName": "Prometheus"
|
|
}
|
|
],
|
|
"__requires": [
|
|
{ "type": "grafana", "id": "grafana", "name": "Grafana", "version": "9.0.0" },
|
|
{ "type": "datasource", "id": "prometheus", "name": "Prometheus", "version": "1.0.0" },
|
|
{ "type": "panel", "id": "timeseries", "name": "Time series", "version": "" },
|
|
{ "type": "panel", "id": "stat", "name": "Stat", "version": "" },
|
|
{ "type": "panel", "id": "gauge", "name": "Gauge", "version": "" }
|
|
],
|
|
"id": null,
|
|
"uid": "switchboard-overview",
|
|
"title": "Switchboard Core — Overview",
|
|
"description": "System overview: request rates, latency, provider health, token usage, DB pool.",
|
|
"tags": ["switchboard"],
|
|
"timezone": "browser",
|
|
"refresh": "30s",
|
|
"schemaVersion": 38,
|
|
"version": 1,
|
|
"templating": {
|
|
"list": [
|
|
{
|
|
"name": "datasource",
|
|
"type": "datasource",
|
|
"query": "prometheus",
|
|
"current": { "text": "Prometheus", "value": "Prometheus" }
|
|
},
|
|
{
|
|
"name": "namespace",
|
|
"type": "query",
|
|
"datasource": { "type": "prometheus", "uid": "${datasource}" },
|
|
"query": "label_values(switchboard_http_requests_total, namespace)",
|
|
"includeAll": true,
|
|
"current": { "text": "All", "value": "$__all" }
|
|
},
|
|
{
|
|
"name": "pod",
|
|
"type": "query",
|
|
"datasource": { "type": "prometheus", "uid": "${datasource}" },
|
|
"query": "label_values(switchboard_http_requests_total{namespace=~\"$namespace\"}, pod)",
|
|
"includeAll": true,
|
|
"current": { "text": "All", "value": "$__all" }
|
|
}
|
|
]
|
|
},
|
|
"panels": [
|
|
{
|
|
"title": "Request Rate",
|
|
"type": "timeseries",
|
|
"gridPos": { "h": 8, "w": 6, "x": 0, "y": 0 },
|
|
"targets": [
|
|
{
|
|
"expr": "sum(rate(switchboard_http_requests_total{namespace=~\"$namespace\"}[5m]))",
|
|
"legendFormat": "Total req/s"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"title": "Error Rate (5xx)",
|
|
"type": "timeseries",
|
|
"gridPos": { "h": 8, "w": 6, "x": 6, "y": 0 },
|
|
"targets": [
|
|
{
|
|
"expr": "sum(rate(switchboard_http_requests_total{namespace=~\"$namespace\",status=~\"5..\"}[5m])) / sum(rate(switchboard_http_requests_total{namespace=~\"$namespace\"}[5m]))",
|
|
"legendFormat": "5xx rate"
|
|
}
|
|
],
|
|
"fieldConfig": {
|
|
"defaults": {
|
|
"unit": "percentunit",
|
|
"max": 1,
|
|
"thresholds": {
|
|
"steps": [
|
|
{ "color": "green", "value": null },
|
|
{ "color": "yellow", "value": 0.01 },
|
|
{ "color": "red", "value": 0.05 }
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"title": "Request Latency (p50 / p95 / p99)",
|
|
"type": "timeseries",
|
|
"gridPos": { "h": 8, "w": 6, "x": 12, "y": 0 },
|
|
"targets": [
|
|
{
|
|
"expr": "histogram_quantile(0.50, sum(rate(switchboard_http_request_duration_seconds_bucket{namespace=~\"$namespace\"}[5m])) by (le))",
|
|
"legendFormat": "p50"
|
|
},
|
|
{
|
|
"expr": "histogram_quantile(0.95, sum(rate(switchboard_http_request_duration_seconds_bucket{namespace=~\"$namespace\"}[5m])) by (le))",
|
|
"legendFormat": "p95"
|
|
},
|
|
{
|
|
"expr": "histogram_quantile(0.99, sum(rate(switchboard_http_request_duration_seconds_bucket{namespace=~\"$namespace\"}[5m])) by (le))",
|
|
"legendFormat": "p99"
|
|
}
|
|
],
|
|
"fieldConfig": { "defaults": { "unit": "s" } }
|
|
},
|
|
{
|
|
"title": "WebSocket Connections",
|
|
"type": "stat",
|
|
"gridPos": { "h": 8, "w": 6, "x": 18, "y": 0 },
|
|
"targets": [
|
|
{
|
|
"expr": "sum(switchboard_websocket_connections{namespace=~\"$namespace\"})",
|
|
"legendFormat": "Active"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"title": "Completion Rate by Provider",
|
|
"type": "timeseries",
|
|
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 8 },
|
|
"targets": [
|
|
{
|
|
"expr": "sum by (provider_config_id) (rate(switchboard_completions_total{namespace=~\"$namespace\"}[5m]))",
|
|
"legendFormat": "{{provider_config_id}}"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"title": "Completion Latency p95 by Provider",
|
|
"type": "timeseries",
|
|
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 8 },
|
|
"targets": [
|
|
{
|
|
"expr": "histogram_quantile(0.95, sum by (provider_config_id, le) (rate(switchboard_completion_duration_seconds_bucket{namespace=~\"$namespace\"}[5m])))",
|
|
"legendFormat": "{{provider_config_id}}"
|
|
}
|
|
],
|
|
"fieldConfig": { "defaults": { "unit": "s" } }
|
|
},
|
|
{
|
|
"title": "Tokens/min by Model",
|
|
"type": "timeseries",
|
|
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 16 },
|
|
"targets": [
|
|
{
|
|
"expr": "sum by (model_id) (rate(switchboard_completion_tokens_total{namespace=~\"$namespace\"}[5m])) * 60",
|
|
"legendFormat": "{{model_id}}"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"title": "Provider Status",
|
|
"type": "stat",
|
|
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 16 },
|
|
"targets": [
|
|
{
|
|
"expr": "switchboard_provider_status{namespace=~\"$namespace\"}",
|
|
"legendFormat": "{{provider_config_id}}"
|
|
}
|
|
],
|
|
"fieldConfig": {
|
|
"defaults": {
|
|
"mappings": [
|
|
{ "type": "value", "options": { "0": { "text": "Unknown", "color": "text" } } },
|
|
{ "type": "value", "options": { "1": { "text": "Healthy", "color": "green" } } },
|
|
{ "type": "value", "options": { "2": { "text": "Degraded", "color": "yellow" } } },
|
|
{ "type": "value", "options": { "3": { "text": "Down", "color": "red" } } }
|
|
]
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"title": "DB Connection Pool",
|
|
"type": "timeseries",
|
|
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 24 },
|
|
"targets": [
|
|
{
|
|
"expr": "switchboard_db_open_connections{namespace=~\"$namespace\"}",
|
|
"legendFormat": "Open"
|
|
},
|
|
{
|
|
"expr": "switchboard_db_in_use_connections{namespace=~\"$namespace\"}",
|
|
"legendFormat": "In Use"
|
|
},
|
|
{
|
|
"expr": "switchboard_db_idle_connections{namespace=~\"$namespace\"}",
|
|
"legendFormat": "Idle"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"title": "Task Executions",
|
|
"type": "timeseries",
|
|
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 24 },
|
|
"targets": [
|
|
{
|
|
"expr": "sum by (status) (rate(switchboard_task_executions_total{namespace=~\"$namespace\"}[5m]))",
|
|
"legendFormat": "{{status}}"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|