generate Grafana dashboards for remote testnet nodes
This commit is contained in:
parent
07393c8de6
commit
3a6a9f8135
|
@ -32,3 +32,7 @@ build/
|
||||||
*.sqlite3
|
*.sqlite3
|
||||||
|
|
||||||
/local_testnet_data*/
|
/local_testnet_data*/
|
||||||
|
|
||||||
|
# Grafana dashboards
|
||||||
|
/docker/*.json
|
||||||
|
|
||||||
|
|
|
@ -99,8 +99,10 @@ case conf.cmd
|
||||||
of restart_nodes:
|
of restart_nodes:
|
||||||
for n in nodes():
|
for n in nodes():
|
||||||
if n.id mod 2 == 0:
|
if n.id mod 2 == 0:
|
||||||
|
echo &"echo Pulling container image on {n.server} ..."
|
||||||
# This will only print one line: "docker.io/statusteam/nimbus_beacon_node:testnet1".
|
# This will only print one line: "docker.io/statusteam/nimbus_beacon_node:testnet1".
|
||||||
echo &"ssh {n.server} docker pull -q statusteam/nimbus_beacon_node:{conf.network}"
|
echo &"ssh {n.server} docker pull -q statusteam/nimbus_beacon_node:{conf.network}"
|
||||||
|
echo &"echo Starting container {n.container}@{n.server} ..."
|
||||||
# docker-compose will rebuild the container if it detects a newer image.
|
# docker-compose will rebuild the container if it detects a newer image.
|
||||||
# Prints: "Recreating beacon-node-testnet1-1 ... done".
|
# Prints: "Recreating beacon-node-testnet1-1 ... done".
|
||||||
echo &"ssh {n.server} 'cd /docker/{n.container} && docker-compose --compatibility up -d'"
|
echo &"ssh {n.server} 'cd /docker/{n.container} && docker-compose --compatibility up -d'"
|
||||||
|
|
|
@ -64,7 +64,17 @@ if [ "$ETH1_PRIVATE_KEY" != "" ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Building a local beacon_node instance for 'makeDeposits' and 'createTestnet'"
|
echo "Building a local beacon_node instance for 'makeDeposits' and 'createTestnet'"
|
||||||
make NIMFLAGS="-d:insecure -d:testnet_servers_image ${NETWORK_NIM_FLAGS}" beacon_node
|
make -j2 NIMFLAGS="-d:insecure -d:testnet_servers_image ${NETWORK_NIM_FLAGS}" beacon_node process_dashboard
|
||||||
|
|
||||||
|
echo "Generating Grafana dashboards for remote testnet servers"
|
||||||
|
for testnet in 0 1; do
|
||||||
|
./build/process_dashboard \
|
||||||
|
--nodes=20 \
|
||||||
|
--in="tests/simulation/beacon-chain-sim-node0-Grafana-dashboard.json" \
|
||||||
|
--out="docker/beacon-chain-sim-remote-testnet${testnet}-Grafana-dashboard.json" \
|
||||||
|
--type="remote" \
|
||||||
|
--testnet="${testnet}"
|
||||||
|
done
|
||||||
|
|
||||||
cd docker
|
cd docker
|
||||||
|
|
||||||
|
@ -104,7 +114,7 @@ if [[ $PUBLISH_TESTNET_RESETS != "0" ]]; then
|
||||||
# TODO If we try to use direct piping here, bash doesn't execute all of the commands.
|
# TODO If we try to use direct piping here, bash doesn't execute all of the commands.
|
||||||
# The reasons for this are unclear at the moment.
|
# The reasons for this are unclear at the moment.
|
||||||
|
|
||||||
../env.sh nim --verbosity:0 manage_testnet_hosts.nims reset_network \
|
../env.sh nim --verbosity:0 --hints:off manage_testnet_hosts.nims reset_network \
|
||||||
--network=$NETWORK \
|
--network=$NETWORK \
|
||||||
--deposits-dir="$DEPOSITS_DIR_ABS" \
|
--deposits-dir="$DEPOSITS_DIR_ABS" \
|
||||||
--network-data-dir="$NETWORK_DIR_ABS" \
|
--network-data-dir="$NETWORK_DIR_ABS" \
|
||||||
|
@ -130,7 +140,7 @@ if [[ $PUBLISH_TESTNET_RESETS != "0" ]]; then
|
||||||
git push
|
git push
|
||||||
popd
|
popd
|
||||||
|
|
||||||
../env.sh nim --verbosity:0 manage_testnet_hosts.nims restart_nodes \
|
../env.sh nim --verbosity:0 --hints:off manage_testnet_hosts.nims restart_nodes \
|
||||||
--network=$NETWORK \
|
--network=$NETWORK \
|
||||||
> /tmp/restart-nodes.sh
|
> /tmp/restart-nodes.sh
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,22 @@
|
||||||
"id": 13,
|
"id": 13,
|
||||||
"links": [],
|
"links": [],
|
||||||
"panels": [
|
"panels": [
|
||||||
|
{
|
||||||
|
"content": "",
|
||||||
|
"datasource": null,
|
||||||
|
"gridPos": {
|
||||||
|
"h": 1,
|
||||||
|
"w": 24,
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"id": 44,
|
||||||
|
"mode": "markdown",
|
||||||
|
"timeFrom": null,
|
||||||
|
"timeShift": null,
|
||||||
|
"title": "node #0",
|
||||||
|
"type": "text"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"aliasColors": {},
|
"aliasColors": {},
|
||||||
"bars": false,
|
"bars": false,
|
||||||
|
@ -59,7 +75,7 @@
|
||||||
"h": 6,
|
"h": 6,
|
||||||
"w": 14,
|
"w": 14,
|
||||||
"x": 0,
|
"x": 0,
|
||||||
"y": 0
|
"y": 1
|
||||||
},
|
},
|
||||||
"hiddenSeries": false,
|
"hiddenSeries": false,
|
||||||
"id": 2,
|
"id": 2,
|
||||||
|
@ -179,7 +195,7 @@
|
||||||
"h": 5,
|
"h": 5,
|
||||||
"w": 10,
|
"w": 10,
|
||||||
"x": 14,
|
"x": 14,
|
||||||
"y": 0
|
"y": 1
|
||||||
},
|
},
|
||||||
"hiddenSeries": false,
|
"hiddenSeries": false,
|
||||||
"id": 16,
|
"id": 16,
|
||||||
|
@ -273,7 +289,7 @@
|
||||||
"h": 5,
|
"h": 5,
|
||||||
"w": 10,
|
"w": 10,
|
||||||
"x": 14,
|
"x": 14,
|
||||||
"y": 5
|
"y": 6
|
||||||
},
|
},
|
||||||
"hiddenSeries": false,
|
"hiddenSeries": false,
|
||||||
"id": 20,
|
"id": 20,
|
||||||
|
@ -369,7 +385,7 @@
|
||||||
"h": 6,
|
"h": 6,
|
||||||
"w": 14,
|
"w": 14,
|
||||||
"x": 0,
|
"x": 0,
|
||||||
"y": 6
|
"y": 7
|
||||||
},
|
},
|
||||||
"hiddenSeries": false,
|
"hiddenSeries": false,
|
||||||
"id": 18,
|
"id": 18,
|
||||||
|
@ -464,7 +480,7 @@
|
||||||
"h": 5,
|
"h": 5,
|
||||||
"w": 10,
|
"w": 10,
|
||||||
"x": 14,
|
"x": 14,
|
||||||
"y": 10
|
"y": 11
|
||||||
},
|
},
|
||||||
"hiddenSeries": false,
|
"hiddenSeries": false,
|
||||||
"id": 24,
|
"id": 24,
|
||||||
|
@ -553,7 +569,7 @@
|
||||||
"h": 6,
|
"h": 6,
|
||||||
"w": 14,
|
"w": 14,
|
||||||
"x": 0,
|
"x": 0,
|
||||||
"y": 12
|
"y": 13
|
||||||
},
|
},
|
||||||
"hiddenSeries": false,
|
"hiddenSeries": false,
|
||||||
"id": 22,
|
"id": 22,
|
||||||
|
@ -656,7 +672,7 @@
|
||||||
"h": 2,
|
"h": 2,
|
||||||
"w": 5,
|
"w": 5,
|
||||||
"x": 14,
|
"x": 14,
|
||||||
"y": 15
|
"y": 16
|
||||||
},
|
},
|
||||||
"id": 6,
|
"id": 6,
|
||||||
"interval": null,
|
"interval": null,
|
||||||
|
@ -739,7 +755,7 @@
|
||||||
"h": 2,
|
"h": 2,
|
||||||
"w": 5,
|
"w": 5,
|
||||||
"x": 19,
|
"x": 19,
|
||||||
"y": 15
|
"y": 16
|
||||||
},
|
},
|
||||||
"id": 8,
|
"id": 8,
|
||||||
"interval": null,
|
"interval": null,
|
||||||
|
@ -822,7 +838,7 @@
|
||||||
"h": 2,
|
"h": 2,
|
||||||
"w": 3,
|
"w": 3,
|
||||||
"x": 14,
|
"x": 14,
|
||||||
"y": 17
|
"y": 18
|
||||||
},
|
},
|
||||||
"id": 28,
|
"id": 28,
|
||||||
"interval": null,
|
"interval": null,
|
||||||
|
@ -908,7 +924,7 @@
|
||||||
"h": 2,
|
"h": 2,
|
||||||
"w": 4,
|
"w": 4,
|
||||||
"x": 17,
|
"x": 17,
|
||||||
"y": 17
|
"y": 18
|
||||||
},
|
},
|
||||||
"id": 13,
|
"id": 13,
|
||||||
"interval": null,
|
"interval": null,
|
||||||
|
@ -993,7 +1009,7 @@
|
||||||
"h": 2,
|
"h": 2,
|
||||||
"w": 3,
|
"w": 3,
|
||||||
"x": 21,
|
"x": 21,
|
||||||
"y": 17
|
"y": 18
|
||||||
},
|
},
|
||||||
"id": 14,
|
"id": 14,
|
||||||
"interval": null,
|
"interval": null,
|
||||||
|
@ -1068,7 +1084,7 @@
|
||||||
"h": 6,
|
"h": 6,
|
||||||
"w": 14,
|
"w": 14,
|
||||||
"x": 0,
|
"x": 0,
|
||||||
"y": 18
|
"y": 19
|
||||||
},
|
},
|
||||||
"hiddenSeries": false,
|
"hiddenSeries": false,
|
||||||
"id": 38,
|
"id": 38,
|
||||||
|
@ -1113,7 +1129,7 @@
|
||||||
"timeFrom": null,
|
"timeFrom": null,
|
||||||
"timeRegions": [],
|
"timeRegions": [],
|
||||||
"timeShift": null,
|
"timeShift": null,
|
||||||
"title": "blocks",
|
"title": "blocks #0",
|
||||||
"tooltip": {
|
"tooltip": {
|
||||||
"shared": true,
|
"shared": true,
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
|
@ -1172,7 +1188,7 @@
|
||||||
"h": 2,
|
"h": 2,
|
||||||
"w": 3,
|
"w": 3,
|
||||||
"x": 14,
|
"x": 14,
|
||||||
"y": 19
|
"y": 20
|
||||||
},
|
},
|
||||||
"id": 32,
|
"id": 32,
|
||||||
"interval": null,
|
"interval": null,
|
||||||
|
@ -1256,7 +1272,7 @@
|
||||||
"h": 2,
|
"h": 2,
|
||||||
"w": 4,
|
"w": 4,
|
||||||
"x": 17,
|
"x": 17,
|
||||||
"y": 19
|
"y": 20
|
||||||
},
|
},
|
||||||
"id": 34,
|
"id": 34,
|
||||||
"interval": null,
|
"interval": null,
|
||||||
|
@ -1306,7 +1322,7 @@
|
||||||
"thresholds": "",
|
"thresholds": "",
|
||||||
"timeFrom": null,
|
"timeFrom": null,
|
||||||
"timeShift": null,
|
"timeShift": null,
|
||||||
"title": "last justified epoch #0",
|
"title": "current justified epoch #0",
|
||||||
"type": "singlestat",
|
"type": "singlestat",
|
||||||
"valueFontSize": "80%",
|
"valueFontSize": "80%",
|
||||||
"valueMaps": [
|
"valueMaps": [
|
||||||
|
@ -1341,7 +1357,7 @@
|
||||||
"h": 2,
|
"h": 2,
|
||||||
"w": 3,
|
"w": 3,
|
||||||
"x": 21,
|
"x": 21,
|
||||||
"y": 19
|
"y": 20
|
||||||
},
|
},
|
||||||
"id": 40,
|
"id": 40,
|
||||||
"interval": null,
|
"interval": null,
|
||||||
|
@ -1426,7 +1442,7 @@
|
||||||
"h": 2,
|
"h": 2,
|
||||||
"w": 3,
|
"w": 3,
|
||||||
"x": 14,
|
"x": 14,
|
||||||
"y": 21
|
"y": 22
|
||||||
},
|
},
|
||||||
"id": 12,
|
"id": 12,
|
||||||
"interval": null,
|
"interval": null,
|
||||||
|
@ -1508,7 +1524,7 @@
|
||||||
"h": 2,
|
"h": 2,
|
||||||
"w": 4,
|
"w": 4,
|
||||||
"x": 17,
|
"x": 17,
|
||||||
"y": 21
|
"y": 22
|
||||||
},
|
},
|
||||||
"id": 36,
|
"id": 36,
|
||||||
"interval": null,
|
"interval": null,
|
||||||
|
@ -1570,82 +1586,6 @@
|
||||||
],
|
],
|
||||||
"valueName": "current"
|
"valueName": "current"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"cacheTimeout": null,
|
|
||||||
"colorBackground": false,
|
|
||||||
"colorValue": false,
|
|
||||||
"colors": [
|
|
||||||
"#299c46",
|
|
||||||
"rgba(237, 129, 40, 0.89)",
|
|
||||||
"#d44a3a"
|
|
||||||
],
|
|
||||||
"datasource": null,
|
|
||||||
"format": "none",
|
|
||||||
"gauge": {
|
|
||||||
"maxValue": 100,
|
|
||||||
"minValue": 0,
|
|
||||||
"show": false,
|
|
||||||
"thresholdLabels": false,
|
|
||||||
"thresholdMarkers": true
|
|
||||||
},
|
|
||||||
"gridPos": {
|
|
||||||
"h": 12,
|
|
||||||
"w": 10,
|
|
||||||
"x": 14,
|
|
||||||
"y": 23
|
|
||||||
},
|
|
||||||
"id": 42,
|
|
||||||
"interval": null,
|
|
||||||
"links": [],
|
|
||||||
"mappingType": 1,
|
|
||||||
"mappingTypes": [
|
|
||||||
{
|
|
||||||
"name": "value to text",
|
|
||||||
"value": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "range to text",
|
|
||||||
"value": 2
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"maxDataPoints": 100,
|
|
||||||
"nullPointMode": "connected",
|
|
||||||
"nullText": null,
|
|
||||||
"postfix": "",
|
|
||||||
"postfixFontSize": "50%",
|
|
||||||
"prefix": "",
|
|
||||||
"prefixFontSize": "50%",
|
|
||||||
"rangeMaps": [
|
|
||||||
{
|
|
||||||
"from": "null",
|
|
||||||
"text": "N/A",
|
|
||||||
"to": "null"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"sparkline": {
|
|
||||||
"fillColor": "rgba(31, 118, 189, 0.18)",
|
|
||||||
"full": false,
|
|
||||||
"lineColor": "rgb(31, 120, 193)",
|
|
||||||
"show": false,
|
|
||||||
"ymax": null,
|
|
||||||
"ymin": null
|
|
||||||
},
|
|
||||||
"tableColumn": "",
|
|
||||||
"thresholds": "",
|
|
||||||
"timeFrom": null,
|
|
||||||
"timeShift": null,
|
|
||||||
"title": "spacer #0",
|
|
||||||
"type": "singlestat",
|
|
||||||
"valueFontSize": "80%",
|
|
||||||
"valueMaps": [
|
|
||||||
{
|
|
||||||
"op": "=",
|
|
||||||
"text": "_",
|
|
||||||
"value": "null"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"valueName": "current"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"aliasColors": {},
|
"aliasColors": {},
|
||||||
"bars": false,
|
"bars": false,
|
||||||
|
@ -1658,7 +1598,7 @@
|
||||||
"h": 5,
|
"h": 5,
|
||||||
"w": 14,
|
"w": 14,
|
||||||
"x": 0,
|
"x": 0,
|
||||||
"y": 24
|
"y": 25
|
||||||
},
|
},
|
||||||
"hiddenSeries": false,
|
"hiddenSeries": false,
|
||||||
"id": 30,
|
"id": 30,
|
||||||
|
@ -1760,7 +1700,7 @@
|
||||||
"h": 6,
|
"h": 6,
|
||||||
"w": 14,
|
"w": 14,
|
||||||
"x": 0,
|
"x": 0,
|
||||||
"y": 29
|
"y": 30
|
||||||
},
|
},
|
||||||
"heatmap": {},
|
"heatmap": {},
|
||||||
"hideZeroBuckets": false,
|
"hideZeroBuckets": false,
|
||||||
|
@ -1817,7 +1757,7 @@
|
||||||
"list": []
|
"list": []
|
||||||
},
|
},
|
||||||
"time": {
|
"time": {
|
||||||
"from": "now-1h",
|
"from": "now-15m",
|
||||||
"to": "now"
|
"to": "now"
|
||||||
},
|
},
|
||||||
"timepicker": {
|
"timepicker": {
|
||||||
|
@ -1840,5 +1780,5 @@
|
||||||
"variables": {
|
"variables": {
|
||||||
"list": []
|
"list": []
|
||||||
},
|
},
|
||||||
"version": 31
|
"version": 35
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,31 @@
|
||||||
import json, parseopt, strutils
|
import json, parseopt, strutils
|
||||||
|
|
||||||
# usage: process_dashboard --nodes=2 --in=node0_dashboard.json --out=all_nodes_dashboard.json
|
# usage: process_dashboard --nodes=2 --in=node0_dashboard.json --out=all_nodes_dashboard.json --type=local --testnet=0
|
||||||
|
type
|
||||||
|
OutputType = enum
|
||||||
|
local
|
||||||
|
remote
|
||||||
var
|
var
|
||||||
p = initOptParser()
|
p = initOptParser()
|
||||||
nodes: int
|
nodes: int
|
||||||
inputFileName, outputFilename: string
|
inputFileName, outputFilename: string
|
||||||
|
outputType = OutputType.local
|
||||||
|
testnet = 0
|
||||||
|
|
||||||
|
let
|
||||||
|
hosts = [
|
||||||
|
"master-01",
|
||||||
|
"node-01",
|
||||||
|
"node-02",
|
||||||
|
"node-03",
|
||||||
|
"node-04",
|
||||||
|
"node-05",
|
||||||
|
"node-06",
|
||||||
|
"node-07",
|
||||||
|
"node-08",
|
||||||
|
"node-09",
|
||||||
|
]
|
||||||
|
nodesPerHost = 2
|
||||||
|
|
||||||
while true:
|
while true:
|
||||||
p.next()
|
p.next()
|
||||||
|
@ -18,6 +39,10 @@ while true:
|
||||||
inputFileName = p.val
|
inputFileName = p.val
|
||||||
elif p.key == "out":
|
elif p.key == "out":
|
||||||
outputFileName = p.val
|
outputFileName = p.val
|
||||||
|
elif p.key == "type":
|
||||||
|
outputType = parseEnum[OutputType](p.val)
|
||||||
|
elif p.key == "testnet":
|
||||||
|
testnet = p.val.parseInt()
|
||||||
else:
|
else:
|
||||||
echo "unsupported argument: ", p.key
|
echo "unsupported argument: ", p.key
|
||||||
of cmdArgument:
|
of cmdArgument:
|
||||||
|
@ -35,6 +60,11 @@ for panel in panels:
|
||||||
gridHeight += panel["gridPos"]["h"].getInt()
|
gridHeight += panel["gridPos"]["h"].getInt()
|
||||||
|
|
||||||
outputData["panels"] = %* []
|
outputData["panels"] = %* []
|
||||||
|
if outputType == OutputType.remote:
|
||||||
|
var annotations = outputData["annotations"]["list"]
|
||||||
|
for annotation in annotations.mitems:
|
||||||
|
annotation["datasource"] = %* "-- Grafana --"
|
||||||
|
|
||||||
for nodeNum in 0 .. (nodes - 1):
|
for nodeNum in 0 .. (nodes - 1):
|
||||||
var
|
var
|
||||||
nodePanels = panels.copy()
|
nodePanels = panels.copy()
|
||||||
|
@ -43,14 +73,30 @@ for nodeNum in 0 .. (nodes - 1):
|
||||||
panel["title"] = %* replace(panel["title"].getStr(), "#0", "#" & $nodeNum)
|
panel["title"] = %* replace(panel["title"].getStr(), "#0", "#" & $nodeNum)
|
||||||
panel["id"] = %* (panelIndex + (nodeNum * numPanels))
|
panel["id"] = %* (panelIndex + (nodeNum * numPanels))
|
||||||
panel["gridPos"]["y"] = %* (panel["gridPos"]["y"].getInt() + (nodeNum * gridHeight))
|
panel["gridPos"]["y"] = %* (panel["gridPos"]["y"].getInt() + (nodeNum * gridHeight))
|
||||||
|
if outputType == OutputType.remote:
|
||||||
|
panel["datasource"] = newJNull()
|
||||||
if panel.hasKey("targets"):
|
if panel.hasKey("targets"):
|
||||||
var targets = panel["targets"]
|
var targets = panel["targets"]
|
||||||
for target in targets.mitems:
|
for target in targets.mitems:
|
||||||
target["expr"] = %* replace(target["expr"].getStr(), "{node=\"0\"}", "{node=\"" & $nodeNum & "\"}")
|
case outputType:
|
||||||
|
of OutputType.local:
|
||||||
|
target["expr"] = %* replace(target["expr"].getStr(), "{node=\"0\"}", "{node=\"" & $nodeNum & "\"}")
|
||||||
|
of OutputType.remote:
|
||||||
|
# The remote Prometheus instance polls once per minute, so the
|
||||||
|
# minimum rate() interval is 2 minutes.
|
||||||
|
target["expr"] = %* multiReplace(target["expr"].getStr(),
|
||||||
|
("{node=\"0\"}", "{container=\"beacon-node-testnet" & $testnet & "-" & $((nodeNum mod 2) + 1) & "\",instance=\"" & (hosts[nodeNum div nodesPerHost]) & ".aws-eu-central-1a.nimbus.test\"}"),
|
||||||
|
("[2s]", "[2m]"),
|
||||||
|
("[4s]) * 3", "[2m]) * 120"))
|
||||||
outputData["panels"].add(panel)
|
outputData["panels"].add(panel)
|
||||||
panelIndex.inc()
|
panelIndex.inc()
|
||||||
|
|
||||||
outputData["uid"] = %* (outputData["uid"].getStr() & "a")
|
case outputType:
|
||||||
outputData["title"] = %* (outputData["title"].getStr() & " (all nodes)")
|
of OutputType.local:
|
||||||
|
outputData["title"] = %* (outputData["title"].getStr() & " (all nodes)")
|
||||||
|
outputData["uid"] = %* (outputData["uid"].getStr() & "a")
|
||||||
|
of OutputType.remote:
|
||||||
|
outputData["title"] = %* ("Nimbus testnet" & $testnet)
|
||||||
|
outputData["uid"] = %* (outputData["uid"].getStr() & $testnet)
|
||||||
writeFile(outputFilename, pretty(outputData))
|
writeFile(outputFilename, pretty(outputData))
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue