feat(simulator): Grafana monitoring over generated Parquet
Monitoring compose profile: dependency-free Prometheus exporter that scans the Parquet output with DuckDB (rows, detections, pose frames, battery, RSSI, link distance, bytes on disk), Prometheus scrape config and a provisioned Grafana dashboard. Demonstrates the observability doctrine: fleet statistics derived from the data platform itself.
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
{
|
||||
"uid": "swarm-fleet",
|
||||
"title": "Swarm Fleet — generated data",
|
||||
"tags": ["swarm"],
|
||||
"timezone": "utc",
|
||||
"schemaVersion": 39,
|
||||
"version": 1,
|
||||
"refresh": "5s",
|
||||
"time": { "from": "now-15m", "to": "now" },
|
||||
"panels": [
|
||||
{
|
||||
"id": 1, "type": "stat", "title": "Telemetry rows",
|
||||
"gridPos": { "h": 5, "w": 4, "x": 0, "y": 0 },
|
||||
"datasource": { "type": "prometheus", "uid": "swarm-prom" },
|
||||
"targets": [{ "expr": "sum(swarm_rows_total)", "instant": true, "refId": "A" }],
|
||||
"options": { "reduceOptions": { "calcs": ["lastNotNull"] }, "colorMode": "value" },
|
||||
"fieldConfig": { "defaults": { "unit": "short", "color": { "mode": "fixed", "fixedColor": "blue" } }, "overrides": [] }
|
||||
},
|
||||
{
|
||||
"id": 2, "type": "stat", "title": "Detections",
|
||||
"gridPos": { "h": 5, "w": 4, "x": 4, "y": 0 },
|
||||
"datasource": { "type": "prometheus", "uid": "swarm-prom" },
|
||||
"targets": [{ "expr": "sum(swarm_detections_total)", "instant": true, "refId": "A" }],
|
||||
"options": { "reduceOptions": { "calcs": ["lastNotNull"] }, "colorMode": "value" },
|
||||
"fieldConfig": { "defaults": { "unit": "short", "color": { "mode": "fixed", "fixedColor": "green" } }, "overrides": [] }
|
||||
},
|
||||
{
|
||||
"id": 3, "type": "stat", "title": "Pose frames (sent+received)",
|
||||
"gridPos": { "h": 5, "w": 4, "x": 8, "y": 0 },
|
||||
"datasource": { "type": "prometheus", "uid": "swarm-prom" },
|
||||
"targets": [{ "expr": "sum(swarm_state_frames_total)", "instant": true, "refId": "A" }],
|
||||
"options": { "reduceOptions": { "calcs": ["lastNotNull"] }, "colorMode": "value" },
|
||||
"fieldConfig": { "defaults": { "unit": "short" }, "overrides": [] }
|
||||
},
|
||||
{
|
||||
"id": 4, "type": "stat", "title": "Parquet on disk",
|
||||
"gridPos": { "h": 5, "w": 4, "x": 12, "y": 0 },
|
||||
"datasource": { "type": "prometheus", "uid": "swarm-prom" },
|
||||
"targets": [{ "expr": "sum(swarm_parquet_bytes)", "instant": true, "refId": "A" }],
|
||||
"options": { "reduceOptions": { "calcs": ["lastNotNull"] }, "colorMode": "value" },
|
||||
"fieldConfig": { "defaults": { "unit": "bytes", "color": { "mode": "fixed", "fixedColor": "purple" } }, "overrides": [] }
|
||||
},
|
||||
{
|
||||
"id": 5, "type": "stat", "title": "Parquet files",
|
||||
"gridPos": { "h": 5, "w": 4, "x": 16, "y": 0 },
|
||||
"datasource": { "type": "prometheus", "uid": "swarm-prom" },
|
||||
"targets": [{ "expr": "swarm_parquet_files", "instant": true, "refId": "A" }],
|
||||
"options": { "reduceOptions": { "calcs": ["lastNotNull"] } },
|
||||
"fieldConfig": { "defaults": { "unit": "short" }, "overrides": [] }
|
||||
},
|
||||
{
|
||||
"id": 6, "type": "gauge", "title": "Fleet battery (min)",
|
||||
"gridPos": { "h": 5, "w": 4, "x": 20, "y": 0 },
|
||||
"datasource": { "type": "prometheus", "uid": "swarm-prom" },
|
||||
"targets": [{ "expr": "min(swarm_battery_pct)", "instant": true, "refId": "A" }],
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"unit": "percent", "min": 0, "max": 100,
|
||||
"thresholds": { "mode": "absolute", "steps": [
|
||||
{ "color": "red", "value": null }, { "color": "yellow", "value": 30 }, { "color": "green", "value": 60 }
|
||||
] }
|
||||
}, "overrides": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 7, "type": "timeseries", "title": "Telemetry rows by drone",
|
||||
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 5 },
|
||||
"datasource": { "type": "prometheus", "uid": "swarm-prom" },
|
||||
"targets": [{ "expr": "sum by (drone) (swarm_rows_total)", "legendFormat": "{{drone}}", "refId": "A" }],
|
||||
"fieldConfig": { "defaults": { "unit": "short", "custom": { "fillOpacity": 12 } }, "overrides": [] }
|
||||
},
|
||||
{
|
||||
"id": 8, "type": "timeseries", "title": "Rows by sensor (fleet)",
|
||||
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 5 },
|
||||
"datasource": { "type": "prometheus", "uid": "swarm-prom" },
|
||||
"targets": [{ "expr": "sum by (sensor) (swarm_rows_total)", "legendFormat": "{{sensor}}", "refId": "A" }],
|
||||
"fieldConfig": { "defaults": { "unit": "short", "custom": { "fillOpacity": 12 } }, "overrides": [] }
|
||||
},
|
||||
{
|
||||
"id": 9, "type": "timeseries", "title": "Battery per drone",
|
||||
"gridPos": { "h": 8, "w": 8, "x": 0, "y": 13 },
|
||||
"datasource": { "type": "prometheus", "uid": "swarm-prom" },
|
||||
"targets": [{ "expr": "swarm_battery_pct", "legendFormat": "{{drone}}", "refId": "A" }],
|
||||
"fieldConfig": { "defaults": { "unit": "percent", "min": 0, "max": 100 }, "overrides": [] }
|
||||
},
|
||||
{
|
||||
"id": 10, "type": "timeseries", "title": "RSSI per link",
|
||||
"gridPos": { "h": 8, "w": 8, "x": 8, "y": 13 },
|
||||
"datasource": { "type": "prometheus", "uid": "swarm-prom" },
|
||||
"targets": [{ "expr": "swarm_rssi_dbm", "legendFormat": "{{drone}} ← {{peer}}", "refId": "A" }],
|
||||
"fieldConfig": { "defaults": { "unit": "dBm" }, "overrides": [] }
|
||||
},
|
||||
{
|
||||
"id": 11, "type": "timeseries", "title": "Inter-drone distance",
|
||||
"gridPos": { "h": 8, "w": 8, "x": 16, "y": 13 },
|
||||
"datasource": { "type": "prometheus", "uid": "swarm-prom" },
|
||||
"targets": [{ "expr": "swarm_peer_distance_m", "legendFormat": "{{drone}} ↔ {{peer}}", "refId": "A" }],
|
||||
"fieldConfig": { "defaults": { "unit": "lengthm" }, "overrides": [] }
|
||||
},
|
||||
{
|
||||
"id": 12, "type": "bargauge", "title": "Detections by class",
|
||||
"gridPos": { "h": 7, "w": 12, "x": 0, "y": 21 },
|
||||
"datasource": { "type": "prometheus", "uid": "swarm-prom" },
|
||||
"targets": [{ "expr": "sum by (cls) (swarm_detections_total)", "legendFormat": "{{cls}}", "instant": true, "refId": "A" }],
|
||||
"options": { "displayMode": "gradient", "orientation": "horizontal", "reduceOptions": { "calcs": ["lastNotNull"] } },
|
||||
"fieldConfig": { "defaults": { "unit": "short", "color": { "mode": "continuous-GrYlRd" } }, "overrides": [] }
|
||||
},
|
||||
{
|
||||
"id": 13, "type": "timeseries", "title": "Pose frames by direction",
|
||||
"gridPos": { "h": 7, "w": 12, "x": 12, "y": 21 },
|
||||
"datasource": { "type": "prometheus", "uid": "swarm-prom" },
|
||||
"targets": [{ "expr": "sum by (drone, direction) (swarm_state_frames_total)", "legendFormat": "{{drone}} {{direction}}", "refId": "A" }],
|
||||
"fieldConfig": { "defaults": { "unit": "short", "custom": { "fillOpacity": 8 } }, "overrides": [] }
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
apiVersion: 1
|
||||
|
||||
providers:
|
||||
- name: swarm
|
||||
folder: ""
|
||||
type: file
|
||||
options:
|
||||
path: /var/lib/grafana/dashboards
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: 1
|
||||
|
||||
datasources:
|
||||
- name: Prometheus
|
||||
uid: swarm-prom
|
||||
type: prometheus
|
||||
access: proxy
|
||||
url: http://prometheus:9090
|
||||
isDefault: true
|
||||
Reference in New Issue
Block a user