diff --git a/docker/telemetry/grafana/dashboards/rippled-peer-quality.json b/docker/telemetry/grafana/dashboards/rippled-peer-quality.json new file mode 100644 index 0000000000..a611aad549 --- /dev/null +++ b/docker/telemetry/grafana/dashboards/rippled-peer-quality.json @@ -0,0 +1,391 @@ +{ + "annotations": { + "list": [] + }, + "description": "Peer network quality metrics: latency, divergence, version distribution, upgrade recommendations, disconnects, and connection direction balance. Requires push_metrics.py or equivalent OTel metric source.", + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 1, + "id": null, + "links": [], + "panels": [ + { + "title": "P90 Peer Latency", + "description": "90th percentile peer-to-peer latency in milliseconds over time. High latency indicates network congestion or geographically distant peers.", + "type": "timeseries", + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "expr": "rippled_peer_quality{metric=\"peer_latency_p90_ms\",exported_instance=~\"$node\"}", + "legendFormat": "P90 Latency [{{exported_instance}}]" + } + ], + "fieldConfig": { + "defaults": { + "unit": "ms", + "custom": { + "axisLabel": "Latency (ms)", + "drawStyle": "line", + "lineWidth": 2, + "fillOpacity": 10, + "spanNulls": true, + "insertNulls": false, + "showPoints": "auto", + "pointSize": 3 + }, + "color": { + "mode": "palette-classic" + }, + "thresholds": { + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 200 + }, + { + "color": "red", + "value": 500 + } + ] + } + }, + "overrides": [] + } + }, + { + "title": "Insane/Diverged Peers", + "description": "Count of peers whose ledger state is considered insane or diverged from the network. Non-zero values suggest those peers are misbehaving or on a fork.", + "type": "stat", + "gridPos": { + "h": 8, + "w": 6, + "x": 12, + "y": 0 + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "expr": "rippled_peer_quality{metric=\"peers_insane_count\",exported_instance=~\"$node\"}", + "legendFormat": "Insane Peers [{{exported_instance}}]" + } + ], + "fieldConfig": { + "defaults": { + "unit": "none", + "thresholds": { + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 1 + }, + { + "color": "red", + "value": 3 + } + ] + }, + "custom": {} + }, + "overrides": [] + } + }, + { + "title": "Higher Version Peers %", + "description": "Percentage of connected peers running a higher rippled version. A high percentage suggests this node should be upgraded.", + "type": "stat", + "gridPos": { + "h": 8, + "w": 6, + "x": 18, + "y": 0 + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "expr": "rippled_peer_quality{metric=\"peers_higher_version_pct\",exported_instance=~\"$node\"}", + "legendFormat": "Higher Version % [{{exported_instance}}]" + } + ], + "fieldConfig": { + "defaults": { + "unit": "percent", + "min": 0, + "max": 100, + "thresholds": { + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 30 + }, + { + "color": "red", + "value": 60 + } + ] + }, + "custom": {} + }, + "overrides": [] + } + }, + { + "title": "Upgrade Recommended", + "description": "Whether an upgrade is recommended based on peer version analysis (1=recommended, 0=not needed). Triggered when a majority of peers run a newer version.", + "type": "stat", + "gridPos": { + "h": 8, + "w": 6, + "x": 0, + "y": 8 + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "expr": "rippled_peer_quality{metric=\"upgrade_recommended\",exported_instance=~\"$node\"}", + "legendFormat": "Upgrade [{{exported_instance}}]" + } + ], + "fieldConfig": { + "defaults": { + "unit": "none", + "mappings": [ + { + "type": "value", + "options": { + "0": { "text": "No", "color": "green" } + } + }, + { + "type": "value", + "options": { + "1": { "text": "Yes", "color": "red" } + } + } + ], + "thresholds": { + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 1 + } + ] + }, + "custom": {} + }, + "overrides": [] + } + }, + { + "title": "Resource Disconnects", + "description": "Cumulative peer disconnections due to resource limit violations over time. Rising values indicate aggressive or misbehaving peers being dropped.", + "type": "timeseries", + "gridPos": { + "h": 8, + "w": 10, + "x": 6, + "y": 8 + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "expr": "rippled_Overlay_Peer_Disconnects_Charges{exported_instance=~\"$node\"}", + "legendFormat": "Disconnects [{{exported_instance}}]" + } + ], + "fieldConfig": { + "defaults": { + "unit": "none", + "custom": { + "axisLabel": "Disconnects", + "drawStyle": "line", + "lineWidth": 2, + "fillOpacity": 10, + "spanNulls": true, + "insertNulls": false, + "showPoints": "auto", + "pointSize": 3 + }, + "color": { + "mode": "palette-classic" + } + }, + "overrides": [] + } + }, + { + "title": "Inbound vs Outbound Peers", + "description": "Comparison of active inbound and outbound peer connections. A healthy node should have a balanced mix. All-inbound may indicate NAT/firewall issues preventing outbound connections.", + "type": "bargauge", + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 8 + }, + "options": { + "orientation": "horizontal", + "displayMode": "gradient", + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "expr": "rippled_Peer_Finder_Active_Inbound_Peers{exported_instance=~\"$node\"}", + "legendFormat": "Inbound [{{exported_instance}}]" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "rippled_Peer_Finder_Active_Outbound_Peers{exported_instance=~\"$node\"}", + "legendFormat": "Outbound [{{exported_instance}}]" + } + ], + "fieldConfig": { + "defaults": { + "unit": "none", + "thresholds": { + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "custom": {} + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "Inbound.*" + }, + "properties": [ + { + "id": "color", + "value": { + "mode": "fixed", + "fixedColor": "blue" + } + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "Outbound.*" + }, + "properties": [ + { + "id": "color", + "value": { + "mode": "fixed", + "fixedColor": "orange" + } + } + ] + } + ] + } + } + ], + "schemaVersion": 39, + "tags": ["rippled", "otel", "peer", "network", "telemetry"], + "templating": { + "list": [ + { + "name": "node", + "label": "Node", + "description": "Filter by rippled node (service.instance.id)", + "type": "query", + "query": "label_values(rippled_peer_quality, exported_instance)", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "includeAll": true, + "allValue": ".*", + "current": { + "text": "All", + "value": "$__all" + }, + "multi": true, + "refresh": 2, + "sort": 1 + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "title": "Peer Quality", + "uid": "rippled-peer-quality" +} diff --git a/docker/telemetry/grafana/dashboards/rippled-validator-health.json b/docker/telemetry/grafana/dashboards/rippled-validator-health.json new file mode 100644 index 0000000000..37c00e62ed --- /dev/null +++ b/docker/telemetry/grafana/dashboards/rippled-validator-health.json @@ -0,0 +1,714 @@ +{ + "annotations": { + "list": [] + }, + "description": "Validator health metrics: agreement rates, validation counts, amendment status, UNL expiry, server state tracking, and ledger close rates. Requires push_metrics.py or equivalent OTel metric source.", + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 1, + "id": null, + "links": [], + "panels": [ + { + "title": "--- Validation Agreement ---", + "type": "row", + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "collapsed": false, + "panels": [] + }, + { + "title": "Agreement % (1h)", + "description": "Validation agreement percentage over the last 1 hour. Values below 80% indicate the validator is frequently disagreeing with the network consensus.", + "type": "stat", + "gridPos": { + "h": 8, + "w": 6, + "x": 0, + "y": 1 + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "expr": "rippled_validation_agreement{metric=\"agreement_pct_1h\",exported_instance=~\"$node\"}", + "legendFormat": "Agreement 1h [{{exported_instance}}]" + } + ], + "fieldConfig": { + "defaults": { + "unit": "percent", + "min": 0, + "max": 100, + "thresholds": { + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "yellow", + "value": 80 + }, + { + "color": "green", + "value": 95 + } + ] + }, + "custom": {} + }, + "overrides": [] + } + }, + { + "title": "Agreement % (24h)", + "description": "Validation agreement percentage over the last 24 hours. A sustained value below 90% may indicate configuration drift or network partition.", + "type": "stat", + "gridPos": { + "h": 8, + "w": 6, + "x": 6, + "y": 1 + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "expr": "rippled_validation_agreement{metric=\"agreement_pct_24h\",exported_instance=~\"$node\"}", + "legendFormat": "Agreement 24h [{{exported_instance}}]" + } + ], + "fieldConfig": { + "defaults": { + "unit": "percent", + "min": 0, + "max": 100, + "thresholds": { + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "yellow", + "value": 80 + }, + { + "color": "green", + "value": 95 + } + ] + }, + "custom": {} + }, + "overrides": [] + } + }, + { + "title": "Agreements vs Missed (1h)", + "description": "Comparison of successful agreements and missed validations over 1 hour. High missed count indicates the validator is not participating in consensus rounds.", + "type": "bargauge", + "gridPos": { + "h": 8, + "w": 6, + "x": 12, + "y": 1 + }, + "options": { + "orientation": "horizontal", + "displayMode": "gradient", + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "expr": "rippled_validation_agreement{metric=\"agreements_1h\",exported_instance=~\"$node\"}", + "legendFormat": "Agreements 1h [{{exported_instance}}]" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "rippled_validation_agreement{metric=\"missed_1h\",exported_instance=~\"$node\"}", + "legendFormat": "Missed 1h [{{exported_instance}}]" + } + ], + "fieldConfig": { + "defaults": { + "unit": "none", + "thresholds": { + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "custom": {} + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "Missed.*" + }, + "properties": [ + { + "id": "color", + "value": { + "mode": "fixed", + "fixedColor": "red" + } + } + ] + } + ] + } + }, + { + "title": "Agreements vs Missed (24h)", + "description": "Comparison of successful agreements and missed validations over 24 hours. Provides a longer-term view of validator reliability.", + "type": "bargauge", + "gridPos": { + "h": 8, + "w": 6, + "x": 18, + "y": 1 + }, + "options": { + "orientation": "horizontal", + "displayMode": "gradient", + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "expr": "rippled_validation_agreement{metric=\"agreements_24h\",exported_instance=~\"$node\"}", + "legendFormat": "Agreements 24h [{{exported_instance}}]" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "rippled_validation_agreement{metric=\"missed_24h\",exported_instance=~\"$node\"}", + "legendFormat": "Missed 24h [{{exported_instance}}]" + } + ], + "fieldConfig": { + "defaults": { + "unit": "none", + "thresholds": { + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "custom": {} + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "Missed.*" + }, + "properties": [ + { + "id": "color", + "value": { + "mode": "fixed", + "fixedColor": "red" + } + } + ] + } + ] + } + }, + { + "title": "--- Validation Rates ---", + "type": "row", + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 9 + }, + "collapsed": false, + "panels": [] + }, + { + "title": "Validation Rate", + "description": "Rate of validations sent per minute (5m average). Indicates how actively this node is producing validations. Expected ~10-12/min on mainnet (one per ledger close).", + "type": "stat", + "gridPos": { + "h": 8, + "w": 6, + "x": 0, + "y": 10 + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "expr": "rate(rippled_validations_sent_total{exported_instance=~\"$node\"}[5m]) * 60", + "legendFormat": "Sent/min [{{exported_instance}}]" + } + ], + "fieldConfig": { + "defaults": { + "unit": "none", + "thresholds": { + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "yellow", + "value": 5 + }, + { + "color": "green", + "value": 8 + } + ] + }, + "custom": {} + }, + "overrides": [] + } + }, + { + "title": "Validations Checked Rate", + "description": "Rate of validations checked (received from peers) per minute (5m average). Indicates how many validations from the network are being processed.", + "type": "stat", + "gridPos": { + "h": 8, + "w": 6, + "x": 6, + "y": 10 + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "expr": "rate(rippled_validations_checked_total{exported_instance=~\"$node\"}[5m]) * 60", + "legendFormat": "Checked/min [{{exported_instance}}]" + } + ], + "fieldConfig": { + "defaults": { + "unit": "none", + "custom": {} + }, + "overrides": [] + } + }, + { + "title": "Amendment Blocked", + "description": "Whether the node is amendment-blocked (1=blocked, 0=normal). An amendment-blocked node cannot validate and needs a software upgrade.", + "type": "stat", + "gridPos": { + "h": 8, + "w": 6, + "x": 12, + "y": 10 + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "expr": "rippled_validator_health{metric=\"amendment_blocked\",exported_instance=~\"$node\"}", + "legendFormat": "Blocked [{{exported_instance}}]" + } + ], + "fieldConfig": { + "defaults": { + "unit": "none", + "mappings": [ + { + "type": "value", + "options": { + "0": { "text": "OK", "color": "green" } + } + }, + { + "type": "value", + "options": { + "1": { "text": "BLOCKED", "color": "red" } + } + } + ], + "thresholds": { + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 1 + } + ] + }, + "custom": {} + }, + "overrides": [] + } + }, + { + "title": "UNL Expiry (days)", + "description": "Days until the UNL (Unique Node List) expires. A value below 7 requires attention to renew the UNL before it expires and the validator stops trusting peers.", + "type": "stat", + "gridPos": { + "h": 8, + "w": 6, + "x": 18, + "y": 10 + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "expr": "rippled_validator_health{metric=\"unl_expiry_days\",exported_instance=~\"$node\"}", + "legendFormat": "UNL Expiry [{{exported_instance}}]" + } + ], + "fieldConfig": { + "defaults": { + "unit": "none", + "thresholds": { + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "yellow", + "value": 7 + }, + { + "color": "green", + "value": 30 + } + ] + }, + "custom": {} + }, + "overrides": [] + } + }, + { + "title": "--- Server State & Consensus ---", + "type": "row", + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 18 + }, + "collapsed": false, + "panels": [] + }, + { + "title": "Validation Quorum", + "description": "Minimum number of trusted validations needed to declare a ledger validated. Tracks the current quorum requirement from the validator list.", + "type": "stat", + "gridPos": { + "h": 8, + "w": 6, + "x": 0, + "y": 19 + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "expr": "rippled_validator_health{metric=\"validation_quorum\",exported_instance=~\"$node\"}", + "legendFormat": "Quorum [{{exported_instance}}]" + } + ], + "fieldConfig": { + "defaults": { + "unit": "none", + "custom": {} + }, + "overrides": [] + } + }, + { + "title": "State Value Timeline", + "description": "Numeric encoding of the server operating state over time. Useful for correlating state changes with other metrics.", + "type": "timeseries", + "gridPos": { + "h": 8, + "w": 18, + "x": 6, + "y": 19 + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "expr": "rippled_state_tracking{metric=\"state_value\",exported_instance=~\"$node\"}", + "legendFormat": "State [{{exported_instance}}]" + } + ], + "fieldConfig": { + "defaults": { + "unit": "none", + "custom": { + "axisLabel": "State", + "drawStyle": "line", + "lineWidth": 2, + "fillOpacity": 10, + "spanNulls": true, + "insertNulls": false, + "showPoints": "auto", + "pointSize": 3 + }, + "color": { + "mode": "palette-classic" + } + }, + "overrides": [] + } + }, + { + "title": "Time in Current State", + "description": "How long the server has been in its current operating state, in seconds. Short durations with frequent changes indicate instability.", + "type": "stat", + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 27 + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "expr": "rippled_state_tracking{metric=\"time_in_current_state_seconds\",exported_instance=~\"$node\"}", + "legendFormat": "Time in State [{{exported_instance}}]" + } + ], + "fieldConfig": { + "defaults": { + "unit": "s", + "custom": {} + }, + "overrides": [] + } + }, + { + "title": "State Changes Rate", + "description": "Rate of server state changes per hour. A healthy node should have near-zero state changes. Frequent transitions indicate network or configuration issues.", + "type": "stat", + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 27 + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "expr": "rate(rippled_state_changes_total{exported_instance=~\"$node\"}[1h])", + "legendFormat": "Changes/hr [{{exported_instance}}]" + } + ], + "fieldConfig": { + "defaults": { + "unit": "none", + "thresholds": { + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 1 + }, + { + "color": "red", + "value": 5 + } + ] + }, + "custom": {} + }, + "overrides": [] + } + }, + { + "title": "Ledgers Closed Rate", + "description": "Rate of ledgers closed per minute (5m average). On mainnet, expect roughly 10-12/min. Deviations indicate consensus timing issues.", + "type": "stat", + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 27 + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "expr": "rate(rippled_ledgers_closed_total{exported_instance=~\"$node\"}[5m]) * 60", + "legendFormat": "Closed/min [{{exported_instance}}]" + } + ], + "fieldConfig": { + "defaults": { + "unit": "none", + "thresholds": { + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "yellow", + "value": 5 + }, + { + "color": "green", + "value": 8 + } + ] + }, + "custom": {} + }, + "overrides": [] + } + } + ], + "schemaVersion": 39, + "tags": ["rippled", "otel", "validator", "health", "telemetry"], + "templating": { + "list": [ + { + "name": "node", + "label": "Node", + "description": "Filter by rippled node (service.instance.id)", + "type": "query", + "query": "label_values(rippled_validation_agreement, exported_instance)", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "includeAll": true, + "allValue": ".*", + "current": { + "text": "All", + "value": "$__all" + }, + "multi": true, + "refresh": 2, + "sort": 1 + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "title": "Validator Health", + "uid": "rippled-validator-health" +} diff --git a/docker/telemetry/grafana/dashboards/system-node-health.json b/docker/telemetry/grafana/dashboards/system-node-health.json index 396c89a774..159f106344 100644 --- a/docker/telemetry/grafana/dashboards/system-node-health.json +++ b/docker/telemetry/grafana/dashboards/system-node-health.json @@ -1139,6 +1139,211 @@ }, "overrides": [] } + }, + { + "title": "--- OTel: Ledger Economy ---", + "type": "row", + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 93 + }, + "collapsed": false, + "panels": [] + }, + { + "title": "Base Fee (drops)", + "description": "Current network base transaction fee in drops. Sourced from MetricsRegistry ledger_economy observable gauge. 1 XRP = 1,000,000 drops.", + "type": "stat", + "gridPos": { + "h": 8, + "w": 6, + "x": 0, + "y": 94 + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "expr": "rippled_ledger_economy{metric=\"base_fee_xrp\",exported_instance=~\"$node\"}", + "legendFormat": "Base Fee [{{exported_instance}}]" + } + ], + "fieldConfig": { + "defaults": { + "unit": "none", + "custom": {} + }, + "overrides": [] + } + }, + { + "title": "Reserve Base (drops)", + "description": "Current account reserve base in drops. The minimum XRP balance required to maintain an account on the ledger.", + "type": "stat", + "gridPos": { + "h": 8, + "w": 6, + "x": 6, + "y": 94 + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "expr": "rippled_ledger_economy{metric=\"reserve_base_xrp\",exported_instance=~\"$node\"}", + "legendFormat": "Reserve Base [{{exported_instance}}]" + } + ], + "fieldConfig": { + "defaults": { + "unit": "none", + "custom": {} + }, + "overrides": [] + } + }, + { + "title": "Reserve Inc (drops)", + "description": "Current owner reserve increment in drops. Additional XRP required per owned object (trust lines, offers, etc.).", + "type": "stat", + "gridPos": { + "h": 8, + "w": 6, + "x": 12, + "y": 94 + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "expr": "rippled_ledger_economy{metric=\"reserve_inc_xrp\",exported_instance=~\"$node\"}", + "legendFormat": "Reserve Inc [{{exported_instance}}]" + } + ], + "fieldConfig": { + "defaults": { + "unit": "none", + "custom": {} + }, + "overrides": [] + } + }, + { + "title": "Ledger Age", + "description": "Age of the current open ledger in seconds. Values growing beyond the expected ~4s close interval indicate the node is not closing ledgers on schedule.", + "type": "stat", + "gridPos": { + "h": 8, + "w": 6, + "x": 18, + "y": 94 + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "expr": "rippled_ledger_economy{metric=\"ledger_age_seconds\",exported_instance=~\"$node\"}", + "legendFormat": "Ledger Age [{{exported_instance}}]" + } + ], + "fieldConfig": { + "defaults": { + "unit": "s", + "thresholds": { + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 8 + }, + { + "color": "red", + "value": 20 + } + ] + }, + "custom": {} + }, + "overrides": [] + } + }, + { + "title": "Transaction Rate", + "description": "Current transaction throughput rate from ledger economy metrics. Shows the volume of transactions being processed per interval.", + "type": "timeseries", + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 102 + }, + "options": { + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "expr": "rippled_ledger_economy{metric=\"transaction_rate\",exported_instance=~\"$node\"}", + "legendFormat": "Tx Rate [{{exported_instance}}]" + } + ], + "fieldConfig": { + "defaults": { + "unit": "none", + "custom": { + "axisLabel": "Transactions", + "drawStyle": "line", + "lineWidth": 2, + "fillOpacity": 10, + "spanNulls": true, + "insertNulls": false, + "showPoints": "auto", + "pointSize": 3 + }, + "color": { + "mode": "palette-classic" + } + }, + "overrides": [] + } } ], "schemaVersion": 39,