commit 176e0af844e938c65b08cbb8d5b5dd5e5d720c66 Author: YuruC3 Date: Mon Sep 7 00:06:27 2026 +0200 Init with dashboards diff --git a/Dashboards/README.md b/Dashboards/README.md new file mode 100644 index 0000000..9c86e0f --- /dev/null +++ b/Dashboards/README.md @@ -0,0 +1,23 @@ +# PTP Grafana dashboards + +Import each JSON with **Dashboards -> New -> Import** and select your Prometheus datasource. + +Included: +- `ptp-grandmaster.json` — MOMI / GNSS-PPS / Chrony / PTP +- `ptp-linux-boundary.json` — WOLF-HUNTER-style Linux boundary clock +- `ptp-linux-client.json` — selectable downstream Linux client +- `ptp-nyater.json` — NYATER Nexus boundary clock +- `ptp-homelab-overview.json` — whole timing-chain overview + +The dashboards discover instances from: +- `ptp_linux_node_info{role="grandmaster"}` +- `ptp_linux_node_info{role="boundary"}` +- `ptp_linux_node_info{role="client"}` +- `ptp_nexus_target_info` + +Notes: +- The GM dashboard does **not** treat `ptp_gm_present=0` as a fault, because the local clock itself is the GM. +- The WOLF dashboard gives special attention to `ptp_phc2sys_*`, useful for your JBOD boundary-clock PHCs. +- The NYATER dashboard shows slave/passive port state and Delay_Req migration, which makes redundant-link failover visible. +- Packet-rate panels use Grafana's `$__rate_interval`. +- If `PORT_PROPERTIES_NP` is unavailable, Linux port counters may show PTP port identity instead of the friendly interface name. diff --git a/Dashboards/ptp-grandmaster.json b/Dashboards/ptp-grandmaster.json new file mode 100644 index 0000000..3878379 --- /dev/null +++ b/Dashboards/ptp-grandmaster.json @@ -0,0 +1,852 @@ +{ + "__inputs": [ + { + "name": "DS_PROMETHEUS", + "label": "Prometheus", + "type": "datasource", + "pluginId": "prometheus", + "pluginName": "Prometheus" + } + ], + "annotations": { + "list": [] + }, + "editable": true, + "graphTooltip": 1, + "id": null, + "links": [], + "panels": [ + { + "id": 1, + "type": "row", + "title": "Grandmaster health", + "collapsed": false, + "gridPos": { + "x": 0, + "y": 0, + "w": 24, + "h": 1 + }, + "panels": [] + }, + { + "id": 2, + "type": "stat", + "title": "PPS selected", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 0, + "y": 1, + "w": 4, + "h": 4 + }, + "fieldConfig": { + "defaults": { + "unit": "short", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "green", + "value": 1 + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "refId": "A", + "expr": "max(ptp_gm_chrony_source{instance=\"$instance\",source=\"PPS\",state=\"*\"})", + "legendFormat": "", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 3, + "type": "stat", + "title": "PTP services up", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 4, + "y": 1, + "w": 4, + "h": 4 + }, + "fieldConfig": { + "defaults": { + "unit": "short", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "green", + "value": 1 + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "refId": "A", + "expr": "min(ptp_service_up{instance=\"$instance\"})", + "legendFormat": "", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 4, + "type": "stat", + "title": "Clock class", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 8, + "y": 1, + "w": 4, + "h": 4 + }, + "fieldConfig": { + "defaults": { + "unit": "short", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_grandmaster_clock_class{instance=\"$instance\"}", + "legendFormat": "", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 5, + "type": "stat", + "title": "UTC offset", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 12, + "y": 1, + "w": 4, + "h": 4 + }, + "fieldConfig": { + "defaults": { + "unit": "s", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_current_utc_offset_seconds{instance=\"$instance\"}", + "legendFormat": "", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 6, + "type": "stat", + "title": "Steps removed", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 16, + "y": 1, + "w": 4, + "h": 4 + }, + "fieldConfig": { + "defaults": { + "unit": "short", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_steps_removed{instance=\"$instance\"}", + "legendFormat": "", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 7, + "type": "stat", + "title": "Exporter scrape", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 20, + "y": 1, + "w": 4, + "h": 4 + }, + "fieldConfig": { + "defaults": { + "unit": "short", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "green", + "value": 1 + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_exporter_scrape_success{instance=\"$instance\",stage=\"ok\"}", + "legendFormat": "", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 8, + "type": "row", + "title": "GNSS / Chrony", + "collapsed": false, + "gridPos": { + "x": 0, + "y": 5, + "w": 24, + "h": 1 + }, + "panels": [] + }, + { + "id": 9, + "type": "timeseries", + "title": "Chrony offset", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 0, + "y": 6, + "w": 12, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "unit": "\u00b5s", + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "axisPlacement": "auto", + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "table", + "placement": "bottom", + "calcs": [ + "lastNotNull", + "mean", + "max" + ] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_gm_chrony_system_time_offset_seconds{instance=\"$instance\"} * 1e6", + "legendFormat": "system", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + } + }, + { + "refId": "B", + "expr": "ptp_gm_chrony_last_offset_seconds{instance=\"$instance\"} * 1e6", + "legendFormat": "last", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + } + }, + { + "refId": "C", + "expr": "ptp_gm_chrony_rms_offset_seconds{instance=\"$instance\"} * 1e6", + "legendFormat": "RMS", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + } + } + ] + }, + { + "id": 10, + "type": "timeseries", + "title": "Chrony dispersion / delay", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 12, + "y": 6, + "w": 12, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "unit": "\u00b5s", + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "axisPlacement": "auto", + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "table", + "placement": "bottom", + "calcs": [ + "lastNotNull", + "mean", + "max" + ] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_gm_chrony_root_dispersion_seconds{instance=\"$instance\"} * 1e6", + "legendFormat": "dispersion", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + } + }, + { + "refId": "B", + "expr": "ptp_gm_chrony_root_delay_seconds{instance=\"$instance\"} * 1e6", + "legendFormat": "root delay", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + } + } + ] + }, + { + "id": 11, + "type": "timeseries", + "title": "Chrony frequency", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 0, + "y": 14, + "w": 12, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "unit": "ppm", + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "axisPlacement": "auto", + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "table", + "placement": "bottom", + "calcs": [ + "lastNotNull", + "mean", + "max" + ] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_gm_chrony_frequency_ppm{instance=\"$instance\"}", + "legendFormat": "frequency", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + } + }, + { + "refId": "B", + "expr": "ptp_gm_chrony_residual_frequency_ppm{instance=\"$instance\"}", + "legendFormat": "residual", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + } + }, + { + "refId": "C", + "expr": "ptp_gm_chrony_skew_ppm{instance=\"$instance\"}", + "legendFormat": "skew", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + } + } + ] + }, + { + "id": 12, + "type": "timeseries", + "title": "System \u2194 PHC servo", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 12, + "y": 14, + "w": 12, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "unit": "ns", + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "axisPlacement": "auto", + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "table", + "placement": "bottom", + "calcs": [ + "lastNotNull", + "mean", + "max" + ] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_phc2sys_offset_nanoseconds{instance=\"$instance\"}", + "legendFormat": "{{clock}}", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + } + } + ] + }, + { + "id": 13, + "type": "row", + "title": "PTP serving", + "collapsed": false, + "gridPos": { + "x": 0, + "y": 22, + "w": 24, + "h": 1 + }, + "panels": [] + }, + { + "id": 14, + "type": "timeseries", + "title": "PTP message rate", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 0, + "y": 23, + "w": 16, + "h": 9 + }, + "fieldConfig": { + "defaults": { + "unit": "pps", + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "axisPlacement": "auto", + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "table", + "placement": "bottom", + "calcs": [ + "lastNotNull", + "mean", + "max" + ] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "refId": "A", + "expr": "rate(ptp_port_messages_total{instance=\"$instance\",direction=\"tx\",message_type=~\"sync|follow_up|announce|delay_resp\"}[$__rate_interval])", + "legendFormat": "TX {{message_type}}", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + } + }, + { + "refId": "B", + "expr": "rate(ptp_port_messages_total{instance=\"$instance\",direction=\"rx\",message_type=\"delay_req\"}[$__rate_interval])", + "legendFormat": "RX delay_req", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + } + } + ] + }, + { + "id": 15, + "type": "table", + "title": "PMC dataset health", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 16, + "y": 23, + "w": 8, + "h": 9 + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "options": { + "showHeader": true, + "cellHeight": "sm" + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_exporter_pmc_dataset_success{instance=\"$instance\"}", + "legendFormat": "{{dataset}} {{error}}", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + } + ], + "refresh": "10s", + "schemaVersion": 39, + "tags": [ + "ptp", + "67" + ], + "templating": { + "list": [ + { + "name": "instance", + "label": "Grandmaster", + "type": "query", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "query": "label_values(ptp_linux_node_info{role=\"grandmaster\"}, instance)", + "definition": "label_values(ptp_linux_node_info{role=\"grandmaster\"}, instance)", + "refresh": 1, + "sort": 1, + "multi": false, + "includeAll": false, + "current": {}, + "options": [] + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timezone": "browser", + "title": "PTP - Grandmaster", + "uid": "ptp-grandmaster", + "version": 1, + "description": "GNSS/PPS, Chrony and PTP health for Grandmaster." +} \ No newline at end of file diff --git a/Dashboards/ptp-homelab-overview.json b/Dashboards/ptp-homelab-overview.json new file mode 100644 index 0000000..f427dbd --- /dev/null +++ b/Dashboards/ptp-homelab-overview.json @@ -0,0 +1,962 @@ +{ + "__inputs": [ + { + "name": "DS_PROMETHEUS", + "label": "Prometheus", + "type": "datasource", + "pluginId": "prometheus", + "pluginName": "Prometheus" + } + ], + "annotations": { + "list": [] + }, + "editable": true, + "graphTooltip": 1, + "id": null, + "links": [], + "panels": [ + { + "id": 1, + "type": "row", + "title": "Timing chain overview", + "collapsed": false, + "gridPos": { + "x": 0, + "y": 0, + "w": 24, + "h": 1 + }, + "panels": [] + }, + { + "id": 2, + "type": "stat", + "title": "Grandmaster PPS selected", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 0, + "y": 1, + "w": 4, + "h": 4 + }, + "fieldConfig": { + "defaults": { + "unit": "short", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "green", + "value": 1 + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "refId": "A", + "expr": "max(ptp_gm_chrony_source{instance=\"$gm\",source=\"PPS\",state=\"*\"})", + "legendFormat": "", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 3, + "type": "stat", + "title": "BorderClock GM present", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 4, + "y": 1, + "w": 4, + "h": 4 + }, + "fieldConfig": { + "defaults": { + "unit": "short", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "green", + "value": 1 + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_gm_present{instance=\"$boundary\"}", + "legendFormat": "", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 4, + "type": "stat", + "title": "NEXUS locked", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 8, + "y": 1, + "w": 4, + "h": 4 + }, + "fieldConfig": { + "defaults": { + "unit": "short", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "green", + "value": 1 + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_nexus_clock_locked{instance=\"$nexus\"}", + "legendFormat": "", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 5, + "type": "stat", + "title": "BorderClock offset", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 12, + "y": 1, + "w": 4, + "h": 4 + }, + "fieldConfig": { + "defaults": { + "unit": "ns", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_master_offset_nanoseconds{instance=\"$boundary\"}", + "legendFormat": "", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 6, + "type": "stat", + "title": "NEXUS offset", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 16, + "y": 1, + "w": 4, + "h": 4 + }, + "fieldConfig": { + "defaults": { + "unit": "ns", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_nexus_offset_from_master_nanoseconds{instance=\"$nexus\"}", + "legendFormat": "", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 7, + "type": "stat", + "title": "NEXUS steps", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 20, + "y": 1, + "w": 4, + "h": 4 + }, + "fieldConfig": { + "defaults": { + "unit": "short", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_nexus_steps_removed{instance=\"$nexus\"}", + "legendFormat": "", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 8, + "type": "row", + "title": "Offsets", + "collapsed": false, + "gridPos": { + "x": 0, + "y": 5, + "w": 24, + "h": 1 + }, + "panels": [] + }, + { + "id": 9, + "type": "timeseries", + "title": "Grandmaster GNSS/PPS offset", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 0, + "y": 6, + "w": 8, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "unit": "\u00b5s", + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "axisPlacement": "auto", + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "table", + "placement": "bottom", + "calcs": [ + "lastNotNull", + "mean", + "max" + ] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_gm_chrony_system_time_offset_seconds{instance=\"$gm\"} * 1e6", + "legendFormat": "Grandmaster", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + } + } + ] + }, + { + "id": 10, + "type": "timeseries", + "title": "BorderClock PTP offset", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 8, + "y": 6, + "w": 8, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "unit": "ns", + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "axisPlacement": "auto", + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "table", + "placement": "bottom", + "calcs": [ + "lastNotNull", + "mean", + "max" + ] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_master_offset_nanoseconds{instance=\"$boundary\"}", + "legendFormat": "Border Clock", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + } + } + ] + }, + { + "id": 11, + "type": "timeseries", + "title": "NEXUS PTP offset", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 16, + "y": 6, + "w": 8, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "unit": "ns", + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "axisPlacement": "auto", + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "table", + "placement": "bottom", + "calcs": [ + "lastNotNull", + "mean", + "max" + ] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_nexus_offset_from_master_nanoseconds{instance=\"$nexus\"}", + "legendFormat": "NEXUS", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + } + } + ] + }, + { + "id": 12, + "type": "row", + "title": "All Linux PTP nodes", + "collapsed": false, + "gridPos": { + "x": 0, + "y": 14, + "w": 24, + "h": 1 + }, + "panels": [] + }, + { + "id": 13, + "type": "timeseries", + "title": "Offset by Linux instance", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 0, + "y": 15, + "w": 12, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "unit": "ns", + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "axisPlacement": "auto", + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "table", + "placement": "bottom", + "calcs": [ + "lastNotNull", + "mean", + "max" + ] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_master_offset_nanoseconds", + "legendFormat": "{{instance}}", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + } + } + ] + }, + { + "id": 14, + "type": "timeseries", + "title": "Steps removed by Linux instance", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 12, + "y": 15, + "w": 12, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "unit": "short", + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "axisPlacement": "auto", + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "table", + "placement": "bottom", + "calcs": [ + "lastNotNull", + "mean", + "max" + ] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_steps_removed", + "legendFormat": "{{instance}}", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + } + } + ] + }, + { + "id": 15, + "type": "row", + "title": "NEXUS redundancy", + "collapsed": false, + "gridPos": { + "x": 0, + "y": 23, + "w": 24, + "h": 1 + }, + "panels": [] + }, + { + "id": 16, + "type": "table", + "title": "NEXUS upstream states", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 0, + "y": 24, + "w": 8, + "h": 8 + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "options": { + "showHeader": true, + "cellHeight": "sm" + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_nexus_port_state{instance=\"$nexus\"}", + "legendFormat": "{{interface}} {{state}}", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 17, + "type": "timeseries", + "title": "Delay_Req by link", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 8, + "y": 24, + "w": 8, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "unit": "pps", + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "axisPlacement": "auto", + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "table", + "placement": "bottom", + "calcs": [ + "lastNotNull", + "mean", + "max" + ] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "refId": "A", + "expr": "rate(ptp_nexus_port_messages_total{instance=\"$nexus\",direction=\"tx\",message_type=\"delay_request\"}[$__rate_interval])", + "legendFormat": "{{interface}}", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + } + } + ] + }, + { + "id": 18, + "type": "timeseries", + "title": "Linux exporter health", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 16, + "y": 24, + "w": 8, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "unit": "short", + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "axisPlacement": "auto", + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "table", + "placement": "bottom", + "calcs": [ + "lastNotNull", + "mean", + "max" + ] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_exporter_scrape_success{stage=\"ok\"}", + "legendFormat": "{{instance}}", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + } + } + ] + } + ], + "refresh": "10s", + "schemaVersion": 39, + "tags": [ + "ptp", + "67" + ], + "templating": { + "list": [ + { + "name": "gm", + "label": "Grandmaster", + "type": "query", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "query": "label_values(ptp_linux_node_info{role=\"grandmaster\"}, instance)", + "definition": "label_values(ptp_linux_node_info{role=\"grandmaster\"}, instance)", + "refresh": 1, + "sort": 1, + "multi": false, + "includeAll": false, + "current": {}, + "options": [] + }, + { + "name": "boundary", + "label": "Boundary clock", + "type": "query", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "query": "label_values(ptp_linux_node_info{role=\"boundary\"}, instance)", + "definition": "label_values(ptp_linux_node_info{role=\"boundary\"}, instance)", + "refresh": 1, + "sort": 1, + "multi": false, + "includeAll": false, + "current": {}, + "options": [] + }, + { + "name": "nexus", + "label": "Nexus exporter", + "type": "query", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "query": "label_values(ptp_nexus_target_info, instance)", + "definition": "label_values(ptp_nexus_target_info, instance)", + "refresh": 1, + "sort": 1, + "multi": false, + "includeAll": false, + "current": {}, + "options": [] + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timezone": "browser", + "title": "PTP Overview", + "uid": "ptp-overview", + "version": 1 +} \ No newline at end of file diff --git a/Dashboards/ptp-linux-boundary.json b/Dashboards/ptp-linux-boundary.json new file mode 100644 index 0000000..3154b6e --- /dev/null +++ b/Dashboards/ptp-linux-boundary.json @@ -0,0 +1,810 @@ +{ + "__inputs": [ + { + "name": "DS_PROMETHEUS", + "label": "Prometheus", + "type": "datasource", + "pluginId": "prometheus", + "pluginName": "Prometheus" + } + ], + "annotations": { + "list": [] + }, + "editable": true, + "graphTooltip": 1, + "id": null, + "links": [], + "panels": [ + { + "id": 1, + "type": "row", + "title": "Boundary health", + "collapsed": false, + "gridPos": { + "x": 0, + "y": 0, + "w": 24, + "h": 1 + }, + "panels": [] + }, + { + "id": 2, + "type": "stat", + "title": "PTP services up", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 0, + "y": 1, + "w": 4, + "h": 4 + }, + "fieldConfig": { + "defaults": { + "unit": "short", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "green", + "value": 1 + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "refId": "A", + "expr": "min(ptp_service_up{instance=\"$instance\"})", + "legendFormat": "", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 3, + "type": "stat", + "title": "GM present", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 4, + "y": 1, + "w": 4, + "h": 4 + }, + "fieldConfig": { + "defaults": { + "unit": "short", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "green", + "value": 1 + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_gm_present{instance=\"$instance\"}", + "legendFormat": "", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 4, + "type": "stat", + "title": "Offset", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 8, + "y": 1, + "w": 4, + "h": 4 + }, + "fieldConfig": { + "defaults": { + "unit": "ns", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_master_offset_nanoseconds{instance=\"$instance\"}", + "legendFormat": "", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 5, + "type": "stat", + "title": "Path delay", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 12, + "y": 1, + "w": 4, + "h": 4 + }, + "fieldConfig": { + "defaults": { + "unit": "ns", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_mean_path_delay_nanoseconds{instance=\"$instance\"}", + "legendFormat": "", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 6, + "type": "stat", + "title": "Steps removed", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 16, + "y": 1, + "w": 4, + "h": 4 + }, + "fieldConfig": { + "defaults": { + "unit": "short", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_steps_removed{instance=\"$instance\"}", + "legendFormat": "", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 7, + "type": "stat", + "title": "Exporter scrape", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 20, + "y": 1, + "w": 4, + "h": 4 + }, + "fieldConfig": { + "defaults": { + "unit": "short", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "green", + "value": 1 + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_exporter_scrape_success{instance=\"$instance\",stage=\"ok\"}", + "legendFormat": "", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 8, + "type": "row", + "title": "PTP servo", + "collapsed": false, + "gridPos": { + "x": 0, + "y": 5, + "w": 24, + "h": 1 + }, + "panels": [] + }, + { + "id": 9, + "type": "timeseries", + "title": "Offset from selected master", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 0, + "y": 6, + "w": 12, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "unit": "ns", + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "axisPlacement": "auto", + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "table", + "placement": "bottom", + "calcs": [ + "lastNotNull", + "mean", + "max" + ] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_master_offset_nanoseconds{instance=\"$instance\"}", + "legendFormat": "offset", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + } + } + ] + }, + { + "id": 10, + "type": "timeseries", + "title": "Mean path delay", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 12, + "y": 6, + "w": 12, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "unit": "ns", + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "axisPlacement": "auto", + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "table", + "placement": "bottom", + "calcs": [ + "lastNotNull", + "mean", + "max" + ] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_mean_path_delay_nanoseconds{instance=\"$instance\"}", + "legendFormat": "delay", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + } + } + ] + }, + { + "id": 11, + "type": "row", + "title": "JBOD / phc2sys", + "collapsed": false, + "gridPos": { + "x": 0, + "y": 14, + "w": 24, + "h": 1 + }, + "panels": [] + }, + { + "id": 12, + "type": "timeseries", + "title": "phc2sys offset", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 0, + "y": 15, + "w": 12, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "unit": "ns", + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "axisPlacement": "auto", + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "table", + "placement": "bottom", + "calcs": [ + "lastNotNull", + "mean", + "max" + ] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_phc2sys_offset_nanoseconds{instance=\"$instance\"}", + "legendFormat": "{{clock}}", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + } + } + ] + }, + { + "id": 13, + "type": "timeseries", + "title": "phc2sys frequency", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 12, + "y": 15, + "w": 12, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "unit": "ppb", + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "axisPlacement": "auto", + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "table", + "placement": "bottom", + "calcs": [ + "lastNotNull", + "mean", + "max" + ] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_phc2sys_frequency_ppb{instance=\"$instance\"}", + "legendFormat": "{{clock}}", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + } + } + ] + }, + { + "id": 14, + "type": "row", + "title": "Ports", + "collapsed": false, + "gridPos": { + "x": 0, + "y": 23, + "w": 24, + "h": 1 + }, + "panels": [] + }, + { + "id": 15, + "type": "table", + "title": "PTP port states", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 0, + "y": 24, + "w": 8, + "h": 9 + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "options": { + "showHeader": true, + "cellHeight": "sm" + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_port_state{instance=\"$instance\"}", + "legendFormat": "{{interface}} {{state}}", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 16, + "type": "timeseries", + "title": "PTP packet rate by port", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 8, + "y": 24, + "w": 16, + "h": 9 + }, + "fieldConfig": { + "defaults": { + "unit": "pps", + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "axisPlacement": "auto", + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "table", + "placement": "bottom", + "calcs": [ + "lastNotNull", + "mean", + "max" + ] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "refId": "A", + "expr": "rate(ptp_port_messages_total{instance=\"$instance\",message_type=~\"sync|follow_up|announce|delay_req|delay_resp\"}[$__rate_interval])", + "legendFormat": "{{interface}} {{direction}} {{message_type}}", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + } + } + ] + } + ], + "refresh": "10s", + "schemaVersion": 39, + "tags": [ + "ptp", + "67" + ], + "templating": { + "list": [ + { + "name": "instance", + "label": "Boundary clock", + "type": "query", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "query": "label_values(ptp_linux_node_info{role=\"boundary\"}, instance)", + "definition": "label_values(ptp_linux_node_info{role=\"boundary\"}, instance)", + "refresh": 1, + "sort": 1, + "multi": false, + "includeAll": false, + "current": {}, + "options": [] + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timezone": "browser", + "title": "PTP Boundary Clock", + "uid": "ptp-boundary", + "version": 1 +} \ No newline at end of file diff --git a/Dashboards/ptp-linux-client.json b/Dashboards/ptp-linux-client.json new file mode 100644 index 0000000..88426e8 --- /dev/null +++ b/Dashboards/ptp-linux-client.json @@ -0,0 +1,797 @@ +{ + "__inputs": [ + { + "name": "DS_PROMETHEUS", + "label": "Prometheus", + "type": "datasource", + "pluginId": "prometheus", + "pluginName": "Prometheus" + } + ], + "annotations": { + "list": [] + }, + "editable": true, + "graphTooltip": 1, + "id": null, + "links": [], + "panels": [ + { + "id": 1, + "type": "row", + "title": "Client health", + "collapsed": false, + "gridPos": { + "x": 0, + "y": 0, + "w": 24, + "h": 1 + }, + "panels": [] + }, + { + "id": 2, + "type": "stat", + "title": "PTP services up", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 0, + "y": 1, + "w": 4, + "h": 4 + }, + "fieldConfig": { + "defaults": { + "unit": "short", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "green", + "value": 1 + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "refId": "A", + "expr": "min(ptp_service_up{instance=\"$instance\"})", + "legendFormat": "", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 3, + "type": "stat", + "title": "GM present", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 4, + "y": 1, + "w": 4, + "h": 4 + }, + "fieldConfig": { + "defaults": { + "unit": "short", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "green", + "value": 1 + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_gm_present{instance=\"$instance\"}", + "legendFormat": "", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 4, + "type": "stat", + "title": "Offset", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 8, + "y": 1, + "w": 4, + "h": 4 + }, + "fieldConfig": { + "defaults": { + "unit": "ns", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_master_offset_nanoseconds{instance=\"$instance\"}", + "legendFormat": "", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 5, + "type": "stat", + "title": "Path delay", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 12, + "y": 1, + "w": 4, + "h": 4 + }, + "fieldConfig": { + "defaults": { + "unit": "ns", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_mean_path_delay_nanoseconds{instance=\"$instance\"}", + "legendFormat": "", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 6, + "type": "stat", + "title": "Steps removed", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 16, + "y": 1, + "w": 4, + "h": 4 + }, + "fieldConfig": { + "defaults": { + "unit": "short", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_steps_removed{instance=\"$instance\"}", + "legendFormat": "", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 7, + "type": "stat", + "title": "Exporter scrape", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 20, + "y": 1, + "w": 4, + "h": 4 + }, + "fieldConfig": { + "defaults": { + "unit": "short", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "green", + "value": 1 + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_exporter_scrape_success{instance=\"$instance\",stage=\"ok\"}", + "legendFormat": "", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 8, + "type": "row", + "title": "Servo", + "collapsed": false, + "gridPos": { + "x": 0, + "y": 5, + "w": 24, + "h": 1 + }, + "panels": [] + }, + { + "id": 9, + "type": "timeseries", + "title": "PTP offset", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 0, + "y": 6, + "w": 12, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "unit": "ns", + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "axisPlacement": "auto", + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "table", + "placement": "bottom", + "calcs": [ + "lastNotNull", + "mean", + "max" + ] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_master_offset_nanoseconds{instance=\"$instance\"}", + "legendFormat": "PTP offset", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + } + } + ] + }, + { + "id": 10, + "type": "timeseries", + "title": "Mean path delay", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 12, + "y": 6, + "w": 12, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "unit": "ns", + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "axisPlacement": "auto", + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "table", + "placement": "bottom", + "calcs": [ + "lastNotNull", + "mean", + "max" + ] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_mean_path_delay_nanoseconds{instance=\"$instance\"}", + "legendFormat": "delay", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + } + } + ] + }, + { + "id": 11, + "type": "timeseries", + "title": "phc2sys offset", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 0, + "y": 14, + "w": 12, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "unit": "ns", + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "axisPlacement": "auto", + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "table", + "placement": "bottom", + "calcs": [ + "lastNotNull", + "mean", + "max" + ] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_phc2sys_offset_nanoseconds{instance=\"$instance\"}", + "legendFormat": "{{clock}}", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + } + } + ] + }, + { + "id": 12, + "type": "timeseries", + "title": "phc2sys frequency", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 12, + "y": 14, + "w": 12, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "unit": "ppb", + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "axisPlacement": "auto", + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "table", + "placement": "bottom", + "calcs": [ + "lastNotNull", + "mean", + "max" + ] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_phc2sys_frequency_ppb{instance=\"$instance\"}", + "legendFormat": "{{clock}}", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + } + } + ] + }, + { + "id": 13, + "type": "row", + "title": "Port / packets", + "collapsed": false, + "gridPos": { + "x": 0, + "y": 22, + "w": 24, + "h": 1 + }, + "panels": [] + }, + { + "id": 14, + "type": "table", + "title": "PTP port state", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 0, + "y": 23, + "w": 8, + "h": 9 + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "options": { + "showHeader": true, + "cellHeight": "sm" + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_port_state{instance=\"$instance\"}", + "legendFormat": "{{interface}} {{state}}", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 15, + "type": "timeseries", + "title": "PTP packet rate", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 8, + "y": 23, + "w": 16, + "h": 9 + }, + "fieldConfig": { + "defaults": { + "unit": "pps", + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "axisPlacement": "auto", + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "table", + "placement": "bottom", + "calcs": [ + "lastNotNull", + "mean", + "max" + ] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "refId": "A", + "expr": "rate(ptp_port_messages_total{instance=\"$instance\",message_type=~\"sync|follow_up|announce|delay_req|delay_resp\"}[$__rate_interval])", + "legendFormat": "{{direction}} {{message_type}}", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + } + } + ] + } + ], + "refresh": "10s", + "schemaVersion": 39, + "tags": [ + "ptp", + "67" + ], + "templating": { + "list": [ + { + "name": "instance", + "label": "Client", + "type": "query", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "query": "label_values(ptp_linux_node_info{role=\"client\"}, instance)", + "definition": "label_values(ptp_linux_node_info{role=\"client\"}, instance)", + "refresh": 1, + "sort": 1, + "multi": false, + "includeAll": false, + "current": {}, + "options": [] + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timezone": "browser", + "title": "PTP Client", + "uid": "ptp-client", + "version": 1 +} \ No newline at end of file diff --git a/Dashboards/ptp-nyater.json b/Dashboards/ptp-nyater.json new file mode 100644 index 0000000..7d73af9 --- /dev/null +++ b/Dashboards/ptp-nyater.json @@ -0,0 +1,843 @@ +{ + "__inputs": [ + { + "name": "DS_PROMETHEUS", + "label": "Prometheus", + "type": "datasource", + "pluginId": "prometheus", + "pluginName": "Prometheus" + } + ], + "annotations": { + "list": [] + }, + "editable": true, + "graphTooltip": 1, + "id": null, + "links": [], + "panels": [ + { + "id": 1, + "type": "row", + "title": "NYATER health", + "collapsed": false, + "gridPos": { + "x": 0, + "y": 0, + "w": 24, + "h": 1 + }, + "panels": [] + }, + { + "id": 2, + "type": "stat", + "title": "PTP locked", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 0, + "y": 1, + "w": 4, + "h": 4 + }, + "fieldConfig": { + "defaults": { + "unit": "short", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "green", + "value": 1 + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_nexus_clock_locked{instance=\"$instance\"}", + "legendFormat": "", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 3, + "type": "stat", + "title": "Offset", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 4, + "y": 1, + "w": 4, + "h": 4 + }, + "fieldConfig": { + "defaults": { + "unit": "ns", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_nexus_offset_from_master_nanoseconds{instance=\"$instance\"}", + "legendFormat": "", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 4, + "type": "stat", + "title": "Path delay", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 8, + "y": 1, + "w": 4, + "h": 4 + }, + "fieldConfig": { + "defaults": { + "unit": "ns", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_nexus_mean_path_delay_nanoseconds{instance=\"$instance\"}", + "legendFormat": "", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 5, + "type": "stat", + "title": "Steps removed", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 12, + "y": 1, + "w": 4, + "h": 4 + }, + "fieldConfig": { + "defaults": { + "unit": "short", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_nexus_steps_removed{instance=\"$instance\"}", + "legendFormat": "", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 6, + "type": "stat", + "title": "GM class", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 16, + "y": 1, + "w": 4, + "h": 4 + }, + "fieldConfig": { + "defaults": { + "unit": "short", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_nexus_grandmaster_clock_class{instance=\"$instance\"}", + "legendFormat": "", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 7, + "type": "stat", + "title": "SSH scrape", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 20, + "y": 1, + "w": 4, + "h": 4 + }, + "fieldConfig": { + "defaults": { + "unit": "short", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "green", + "value": 1 + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "values": false, + "calcs": [ + "lastNotNull" + ], + "fields": "" + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_nexus_exporter_scrape_success{instance=\"$instance\",error=\"none\"}", + "legendFormat": "", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 8, + "type": "row", + "title": "Servo", + "collapsed": false, + "gridPos": { + "x": 0, + "y": 5, + "w": 24, + "h": 1 + }, + "panels": [] + }, + { + "id": 9, + "type": "timeseries", + "title": "Offset from WOLF-HUNTER", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 0, + "y": 6, + "w": 12, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "unit": "ns", + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "axisPlacement": "auto", + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "table", + "placement": "bottom", + "calcs": [ + "lastNotNull", + "mean", + "max" + ] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_nexus_offset_from_master_nanoseconds{instance=\"$instance\"}", + "legendFormat": "offset", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + } + } + ] + }, + { + "id": 10, + "type": "timeseries", + "title": "Mean path delay", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 12, + "y": 6, + "w": 12, + "h": 8 + }, + "fieldConfig": { + "defaults": { + "unit": "ns", + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "axisPlacement": "auto", + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "table", + "placement": "bottom", + "calcs": [ + "lastNotNull", + "mean", + "max" + ] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_nexus_mean_path_delay_nanoseconds{instance=\"$instance\"}", + "legendFormat": "delay", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + } + } + ] + }, + { + "id": 11, + "type": "row", + "title": "Redundant upstream links", + "collapsed": false, + "gridPos": { + "x": 0, + "y": 14, + "w": 24, + "h": 1 + }, + "panels": [] + }, + { + "id": 12, + "type": "table", + "title": "Port states", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 0, + "y": 15, + "w": 8, + "h": 9 + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "options": { + "showHeader": true, + "cellHeight": "sm" + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_nexus_port_state{instance=\"$instance\"}", + "legendFormat": "{{interface}} {{state}}", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 13, + "type": "timeseries", + "title": "Delay Request rate", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 8, + "y": 15, + "w": 8, + "h": 9 + }, + "fieldConfig": { + "defaults": { + "unit": "pps", + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "axisPlacement": "auto", + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "table", + "placement": "bottom", + "calcs": [ + "lastNotNull", + "mean", + "max" + ] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "refId": "A", + "expr": "rate(ptp_nexus_port_messages_total{instance=\"$instance\",direction=\"tx\",message_type=\"delay_request\"}[$__rate_interval])", + "legendFormat": "{{interface}}", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + } + } + ] + }, + { + "id": 14, + "type": "timeseries", + "title": "Sync / Announce RX rate", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 16, + "y": 15, + "w": 8, + "h": 9 + }, + "fieldConfig": { + "defaults": { + "unit": "pps", + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "axisPlacement": "auto", + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "table", + "placement": "bottom", + "calcs": [ + "lastNotNull", + "mean", + "max" + ] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "refId": "A", + "expr": "rate(ptp_nexus_port_messages_total{instance=\"$instance\",direction=\"rx\",message_type=~\"sync|followup|announce\"}[$__rate_interval])", + "legendFormat": "{{interface}} {{message_type}}", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + } + } + ] + }, + { + "id": 15, + "type": "row", + "title": "Metadata", + "collapsed": false, + "gridPos": { + "x": 0, + "y": 24, + "w": 24, + "h": 1 + }, + "panels": [] + }, + { + "id": 16, + "type": "table", + "title": "Parent / Grandmaster", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 0, + "y": 25, + "w": 12, + "h": 7 + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "options": { + "showHeader": true, + "cellHeight": "sm" + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_nexus_parent_info{instance=\"$instance\"}", + "legendFormat": "", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "instant": true, + "range": false + } + ] + }, + { + "id": 17, + "type": "timeseries", + "title": "Exporter scrape duration", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "x": 12, + "y": 25, + "w": 12, + "h": 7 + }, + "fieldConfig": { + "defaults": { + "unit": "s", + "custom": { + "drawStyle": "line", + "lineInterpolation": "linear", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "axisPlacement": "auto", + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "table", + "placement": "bottom", + "calcs": [ + "lastNotNull", + "mean", + "max" + ] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "refId": "A", + "expr": "ptp_nexus_exporter_scrape_duration_seconds{instance=\"$instance\"}", + "legendFormat": "SSH collection", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + } + } + ] + } + ], + "refresh": "15s", + "schemaVersion": 39, + "tags": [ + "ptp", + "homelab" + ], + "templating": { + "list": [ + { + "name": "instance", + "label": "Nexus exporter", + "type": "query", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "query": "label_values(ptp_nexus_target_info, instance)", + "definition": "label_values(ptp_nexus_target_info, instance)", + "refresh": 1, + "sort": 1, + "multi": false, + "includeAll": false, + "current": {}, + "options": [] + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timezone": "browser", + "title": "PTP - NYATER", + "uid": "ptp-nyater", + "version": 1, + "description": "Cisco Nexus boundary-clock dashboard for NYATER." +} \ No newline at end of file diff --git a/RPi5_configs/README.md b/RPi5_configs/README.md new file mode 100644 index 0000000..03ef3e3 --- /dev/null +++ b/RPi5_configs/README.md @@ -0,0 +1,287 @@ +# Raspberry Pi 5 — GPS/PPS PTP Grandmaster + +This directory contains the files used to turn the Raspberry Pi 5 into the PTP grandmaster for the lab. + +The intended time chain is: + +```text +GT-U7 GNSS + ├─ NMEA over UART ──> gpsd/chrony + └─ PPS on GPIO18 ──> chrony + │ + ▼ + CLOCK_REALTIME (UTC) + │ + phc2sys + │ + ▼ + eth0 NIC PHC + │ + ptp4l + │ + ▼ + PTP domain 0 +``` + +The Pi therefore has two jobs: + +1. discipline the Linux system clock from GNSS/PPS using chrony; and +2. copy that time into the Ethernet PHC and advertise it as the PTP grandmaster. + +## Files in this directory + +| File | Install/use as | Purpose | +|---|---|---| +| `config.txt` | execute the commands in the file once | Adds the Pi 5 UART and PPS overlays to `/boot/firmware/config.txt` | +| `ptp-gm.conf` | `/etc/linuxptp/ptp4l-gm.conf` | `ptp4l` grandmaster configuration | +| `ptp4l-gm.service` | `/etc/systemd/system/ptp4l-gm.service` | Starts the PTP grandmaster | +| `phc2sys-gm.service` | `/etc/systemd/system/phc2sys-gm.service` | Synchronizes the `eth0` PHC from `CLOCK_REALTIME` | +| `ptp_nic_coalesce.service` | `/etc/systemd/system/ptp_nic_coalesce.service` | Optional NIC interrupt-coalescing tuning | + +## 1. Install the required packages + +```bash +sudo apt update +sudo apt install gpsd gpsd-clients pps-tools chrony linuxptp ethtool +``` + +## 2. Configure the Pi UART and PPS input + +The `config.txt` file in this directory contains shell commands that append the required settings to the real Raspberry Pi boot configuration. + +Back up the boot configuration first: + +```bash +sudo cp /boot/firmware/config.txt /boot/firmware/config.txt.pre-ptp +``` + +Then review and execute the commands from `config.txt`. + +The resulting lines in `/boot/firmware/config.txt` should include: + +```text +# GPS UART on GPIO14/GPIO15 for Pi 5 +dtoverlay=uart0-pi5 +init_uart_baud=9600 + +# GPS PPS on physical pin 12 / GPIO18 +dtoverlay=pps-rp1,pin=18,pull-down,schmitt-trigger +``` + +`pps-rp1` is a separate Pi 5 overlay. Make sure `pps-rp1.dtbo` has already been installed in the appropriate overlays directory before rebooting. + +Reboot the Pi: + +```bash +sudo reboot +``` + +After reboot, verify that the UART and PPS device exist: + +```bash +ls -l /dev/ttyAMA0 /dev/pps0 +sudo ppstest /dev/pps0 +``` + +`ppstest` should report a new PPS assertion once per second. + +## 3. Configure gpsd + +Configure `/etc/default/gpsd` so gpsd opens both the GT-U7 UART and PPS device: + +```bash +START_DAEMON="true" +USBAUTO="true" +DEVICES="/dev/ttyAMA0 /dev/pps0" +GPSD_OPTIONS="-n" +``` + +Restart and verify gpsd: + +```bash +sudo systemctl restart gpsd +systemctl status gpsd +cgps -s +``` + +## 4. Configure chrony + +Chrony disciplines `CLOCK_REALTIME` from the GNSS receiver. NMEA identifies the UTC second and PPS supplies the precise second boundary. + +Add the following refclocks to the chrony configuration used by the Pi: + +```text +refclock SHM 0 refid NMEA offset 0.0 precision 1e-1 poll 3 noselect +refclock PPS /dev/pps0 refid PPS lock NMEA poll 3 +``` + +If this Pi should continue serving NTP to the lab, keep the required `allow` networks, for example: + +```text +allow 192.168.0.0/16 +allow 10.0.0.0/8 +allow 172.16.0.0/12 +``` + +Also keep: + +```text +rtcsync +makestep 1 3 +leapseclist /usr/share/zoneinfo/leap-seconds.list +``` + +Do **not** add `local stratum 1` for the GNSS/PPS setup. A selected local refclock already makes chronyd serve the correct NTP stratum; `local` is a separate fallback/local-reference mode. + +Restart chrony and verify that PPS becomes the selected source: + +```bash +sudo systemctl restart chrony +chronyc sources -v +chronyc sourcestats +chronyc tracking +``` + +A healthy setup should show PPS selected (`#* PPS` on common chrony versions). + +The NMEA `offset 0.0` in the example is only a starting point. If the serial NMEA sentence latency is large, measure it and adjust the NMEA offset later. + +## 5. Verify hardware timestamping on `eth0` + +Before enabling PTP, verify the Pi 5 NIC exposes a PHC and hardware TX/RX timestamping: + +```bash +ethtool -T eth0 +``` + +You want hardware TX/RX/raw timestamp support and a non-negative `PTP Hardware Clock` number. + +You can also identify the PHC with: + +```bash +readlink -f /sys/class/net/eth0/device/ptp/ptp* +``` + +## 6. Install the PTP configuration and services + +From this directory, install the files as follows: + +```bash +sudo install -D -m 0644 ptp-gm.conf /etc/linuxptp/ptp4l-gm.conf +sudo install -D -m 0644 ptp4l-gm.service /etc/systemd/system/ptp4l-gm.service +sudo install -D -m 0644 phc2sys-gm.service /etc/systemd/system/phc2sys-gm.service +``` + +The bundled PTP configuration uses: + +```text +domainNumber 0 +network_transport UDPv4 +delay_mechanism E2E +serverOnly 1 +clockClass 6 +clockAccuracy 0xFE +timeSource 0x20 +utc_offset 37 +twoStepFlag 1 +``` + +`clockAccuracy 0xFE` is intentionally conservative until actual accuracy has been measured. The `utc_offset` value is the PTP/TAI-to-UTC offset advertised to clients; review it if a future leap second changes the TAI-UTC difference. + +Reload systemd and enable the services: + +```bash +sudo systemctl daemon-reload +sudo systemctl enable --now ptp4l-gm.service +sudo systemctl enable --now phc2sys-gm.service +``` + +The direction is important: + +```text +chrony: GNSS/PPS -> CLOCK_REALTIME +phc2sys-gm: CLOCK_REALTIME -> eth0 PHC +ptp4l-gm: eth0 PHC -> PTP network +``` + +## 7. Optional NIC coalescing tuning + +`ptp_nic_coalesce.service` applies: + +```bash +ethtool -C eth0 tx-usecs 4 rx-usecs 4 +``` + +Treat this as an optional latency/jitter tuning step, not a requirement for PTP to work. First check what the driver supports: + +```bash +ethtool -c eth0 +``` + +If the settings are accepted and you want to keep them: + +```bash +sudo install -D -m 0644 ptp_nic_coalesce.service /etc/systemd/system/ptp_nic_coalesce.service +sudo systemctl daemon-reload +sudo systemctl enable --now ptp_nic_coalesce.service +``` + +## 8. Verification + +Service state: + +```bash +systemctl status chrony +systemctl status ptp4l-gm +systemctl status phc2sys-gm +``` + +Live logs: + +```bash +journalctl -fu ptp4l-gm +journalctl -fu phc2sys-gm +``` + +Query the local `ptp4l` management socket: + +```bash +sudo pmc -u -b 0 'GET PORT_DATA_SET' +sudo pmc -u -b 0 'GET GRANDMASTER_SETTINGS_NP' +sudo pmc -u -b 0 'GET TIME_STATUS_NP' +``` + +Expected results include: + +```text +portState MASTER/SERVER +timeSource 0x20 +clockClass 6 +clockAccuracy 0xFE +stepsRemoved 0 +``` + +The `grandmasterIdentity` reported here is the identity that should remain visible through WOLF-HUNTER and NYATER. + +## 9. Troubleshooting checklist + +```bash +# PPS exists and pulses +sudo ppstest /dev/pps0 + +# GPS data is arriving +cgps -s + +# chrony actually selected PPS +chronyc sources -v +chronyc tracking + +# eth0 supports hardware PTP +ethtool -T eth0 + +# PTP services are healthy +journalctl -u ptp4l-gm -n 100 --no-pager +journalctl -u phc2sys-gm -n 100 --no-pager +``` + +Do not run another service that also tries to discipline the `eth0` PHC. Chrony may continue to discipline `CLOCK_REALTIME`; that is intentional on the grandmaster.