{ "uid": "factory-infra", "title": "Factory — Infra", "tags": ["factory", "observability", "infra"], "timezone": "browser", "schemaVersion": 39, "version": 1, "editable": true, "refresh": "30s", "time": { "from": "now-6h", "to": "now" }, "panels": [ { "id": 1, "type": "timeseries", "title": "Node disk usage (mountpoint /var/lib)", "datasource": { "type": "prometheus", "uid": "factory-prometheus" }, "gridPos": { "h": 8, "w": 12, "x": 0, "y": 0 }, "fieldConfig": { "defaults": { "unit": "percentunit", "decimals": 1, "thresholds": { "mode": "absolute", "steps": [ { "color": "green", "value": null }, { "color": "red", "value": 0.8 } ] } }, "overrides": [] }, "options": { "legend": { "displayMode": "list", "placement": "bottom" }, "thresholds": { "mode": "absolute" } }, "targets": [ { "refId": "A", "expr": "node_filesystem_usage{mountpoint=\"/var/lib\"}", "legendFormat": "{{instance}}" } ] }, { "id": 2, "type": "timeseries", "title": "Node CPU usage (1 m)", "datasource": { "type": "prometheus", "uid": "factory-prometheus" }, "gridPos": { "h": 8, "w": 12, "x": 12, "y": 0 }, "fieldConfig": { "defaults": { "unit": "percentunit", "custom": { "drawStyle": "line" } }, "overrides": [] }, "options": { "legend": { "displayMode": "list", "placement": "bottom" } }, "targets": [ { "refId": "A", "expr": "1 - avg by (instance) (rate(node_cpu_seconds_total{mode=\"idle\"}[1m]))", "legendFormat": "{{instance}}" } ] }, { "id": 3, "type": "timeseries", "title": "Node memory usage", "datasource": { "type": "prometheus", "uid": "factory-prometheus" }, "gridPos": { "h": 8, "w": 12, "x": 0, "y": 8 }, "fieldConfig": { "defaults": { "unit": "percentunit", "custom": { "drawStyle": "line" } }, "overrides": [] }, "options": { "legend": { "displayMode": "list", "placement": "bottom" } }, "targets": [ { "refId": "A", "expr": "1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes", "legendFormat": "{{instance}}" } ] }, { "id": 4, "type": "timeseries", "title": "DB query p95 per app (10 m) — pool pressure proxy", "datasource": { "type": "prometheus", "uid": "factory-prometheus" }, "gridPos": { "h": 8, "w": 12, "x": 12, "y": 8 }, "fieldConfig": { "defaults": { "unit": "s", "custom": { "drawStyle": "line" } }, "overrides": [] }, "options": { "legend": { "displayMode": "list", "placement": "bottom" } }, "targets": [ { "refId": "A", "expr": "histogram_quantile(0.95, sum by (le) (rate(db_query_duration_seconds_bucket{service_name=\"factory-api\"}[10m])))", "legendFormat": "api" }, { "refId": "B", "expr": "histogram_quantile(0.95, sum by (le) (rate(db_query_duration_seconds_bucket{service_name=\"factory-worker\"}[10m])))", "legendFormat": "worker" } ] }, { "id": 5, "type": "timeseries", "title": "Redis command p95 per app (10 m) — hit-rate pressure proxy", "datasource": { "type": "prometheus", "uid": "factory-prometheus" }, "gridPos": { "h": 8, "w": 12, "x": 0, "y": 16 }, "fieldConfig": { "defaults": { "unit": "s", "custom": { "drawStyle": "line" } }, "overrides": [] }, "options": { "legend": { "displayMode": "list", "placement": "bottom" } }, "targets": [ { "refId": "A", "expr": "histogram_quantile(0.95, sum by (le) (rate(redis_command_duration_seconds_bucket{service_name=\"factory-api\"}[10m])))", "legendFormat": "api" }, { "refId": "B", "expr": "histogram_quantile(0.95, sum by (le) (rate(redis_command_duration_seconds_bucket{service_name=\"factory-worker\"}[10m])))", "legendFormat": "worker" } ] }, { "id": 6, "type": "timeseries", "title": "Storage ops (S3/MinIO) rate + p95 by op", "datasource": { "type": "prometheus", "uid": "factory-prometheus" }, "gridPos": { "h": 8, "w": 12, "x": 12, "y": 16 }, "fieldConfig": { "defaults": { "unit": "ops", "custom": { "drawStyle": "line" } }, "overrides": [] }, "options": { "legend": { "displayMode": "list", "placement": "bottom" } }, "targets": [ { "refId": "A", "expr": "sum by (op) (rate(storage_ops_total{service_name=~\"factory-(api|worker)\"}[5m]))", "legendFormat": "{{op}} /s" }, { "refId": "B", "expr": "histogram_quantile(0.95, sum by (le, op) (rate(storage_op_duration_seconds_bucket{service_name=~\"factory-(api|worker)\"}[10m])))", "legendFormat": "{{op}} p95 (s)" } ] } ], "annotations": { "list": [ { "builtIn": 1, "datasource": { "type": "grafana", "uid": "-- Grafana --" }, "name": "Pod/PG/OS gauges — SPEC GAP", "description": "The spec's Infra dashboard names 'CPU/mem per pod, PG connections vs pool, disk, Redis hit rate, OpenSearch cluster health'. Only disk/CPU/mem (node-exporter, expected-present) + app-side proxies (db/redis p95, storage ops) come from the spec's 14-metric set. Per-pod cgroup metrics (kubelet/cadvisor), PG connection pool gauges, redis hit rate and OpenSearch cluster health are EXPORTER-DEPENDENT metrics outside the 14-set — recorded in infrastructure/observability/README.md (spec-conflict, AGENTS rule 29); the panels use the app-side proxies available from the shipped metrics.", "enable": true, "hide": false, "iconColor": "rgba(255, 96, 96, 1)" } ] } }