Skip to content

Commit

Permalink
feat: implement grafana setup and prometheus support for all nodes (#120
Browse files Browse the repository at this point in the history
)

Co-authored-by: Shreyas S Bhat <[email protected]>
  • Loading branch information
shanithkk and shreyasbhat0 authored Nov 27, 2023
1 parent 8252d03 commit 9a6d95b
Show file tree
Hide file tree
Showing 12 changed files with 255 additions and 58 deletions.
18 changes: 11 additions & 7 deletions local.json
Original file line number Diff line number Diff line change
@@ -1,31 +1,35 @@
{
"chain-type": "testnet",
"chain-type": "local",
"relaychain": {
"name": "kusama",
"name": "rococo",
"nodes": [
{
"name": "alice",
"node-type": "validator",
"port": 9944
"port": 9944,
"prometheus": false
},
{
"name": "bob",
"node-type": "full",
"port": 9945
"port": 9945,
"prometheus": true
}
]
},

"para": {
"acala": {
"bajun": {
"nodes": [
{
"name": "alice",
"node-type": "collator"
"node-type": "collator",
"prometheus": true
},
{
"name": "bob",
"node-type": "full"
"node-type": "full",
"prometheus": false
}
]
}
Expand Down
12 changes: 8 additions & 4 deletions main.star
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
parachain = import_module("./parachain/parachain.star")
relay_chain = import_module("./relaychain/relay-chain.star")
package = import_module("./package_io/build-spec.star")
promethues = import_module("./package_io/promethues.star")
grafana = import_module("./package_io/grafana.star")

def run(plan, args):
plan.upload_files(src = "./parachain/static_files/configs", name = "configs")
service_details = {"relaychains": {}, "parachains": {}, "prometheus": {}}

prometheus_template = read_file("./package_io/static_files/prometheus.yml.tmpl")
service_details = {"relaychains": {}, "parachains": {}, "prometheus": ""}

if args["chain-type"] == "local":
relay_chain_details = relay_chain.start_relay_chains_local(plan, args)
Expand All @@ -21,8 +25,8 @@ def run(plan, args):
parachain_info = parachain.run_testnet_mainnet(plan, args, paras)
service_details["parachains"] = parachain_info

ip = "{0}:{1}".format(relay_chain_details["relay_service_alice"].ip_address, relay_chain_details["relay_service_alice"].ports["prometheus"].number)
prometheus = package.prometheus(plan, args, ip)
service_details["prometheus"] = prometheus
prometheus_address = promethues.launch_prometheus(plan, args, service_details, prometheus_template)
service_details["prometheus"] = prometheus_address
grafana.launch_grafana(plan, grafana)

return service_details
33 changes: 0 additions & 33 deletions package_io/build-spec.star
Original file line number Diff line number Diff line change
Expand Up @@ -28,36 +28,3 @@ def create_edit_and_build_spec(plan, service_name, image, chain_name, command, b
return service

relay_chain = import_module("./constant.star")

def prometheus(plan, args, ip):
create_service_for_build_spec(plan, "prometheus-curl", "badouralix/curl-jq", None)
command = ["sh", "-c", "cp /app/prometheus.yml /tmp/ && sed -i 's/172.16.0.3:9615/{0}/' /tmp/prometheus.yml && /bin/prometheus --config.file=/tmp/prometheus.yml".format(ip)]
prometheus = prometheus_grafana_service(plan, "prometheus", "prom/prometheus:latest", 9090, ip, command, None)
command = ["/run.sh"]
prometheus_grafana_service(plan, "grafana", "grafana/grafana-dev:10.3.0-147071", 3000, ip, command, None)

return prometheus

def prometheus_grafana_service(plan, service_name, image, port, ip, command, build_file = None):
files = {
"/app": "configs",
}
if build_file != None:
files["/build"] = build_file

service = plan.add_service(
name = service_name,
config = ServiceConfig(
image = image,
files = files,
ports = {
"polkadot": PortSpec(port, transport_protocol = "TCP"),
},
public_ports = {
"polkadot": PortSpec(port, transport_protocol = "TCP"),
},
entrypoint = command,
),
)

return service
4 changes: 2 additions & 2 deletions package_io/constant.star
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ CURL_JQ_IMAGE = "badouralix/curl-jq"
NODE_IMAGE = "node:21.1"
PARA_SLOT_REGISTER_SERVICE_NAME = "para-slot-registration"
BINARY_COMMAND_CHAINS = ["manta", "khala", "phala"]
NO_WS_PORT = ["acala", "frequency", "moonbeam", "karura"]
NO_WS_PORT = ["acala", "frequency", "moonbeam", "karura", "ajuna", "bajun"]

DIFFERENT_IMAGES_FOR_MAINNET = {
"centrifuge": "centrifugeio/centrifuge-chain:main-latest",
Expand All @@ -15,7 +15,7 @@ DIFFERENT_IMAGES_FOR_MAINNET = {
DIFFERENT_IMAGES_FOR_TESTNET = {
"frequency": "frequencychain/parachain-node-rococo",
"centrifuge": "centrifugeio/centrifuge-chain:main-latest",
"karura": "acala/mandala-node:latest"
"karura": "acala/mandala-node:latest",
}

CHAIN_COMMAND = ["manta", "moonsama", "interlay", "kintsugi-btc"]
27 changes: 27 additions & 0 deletions package_io/grafana.star
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
def prometheus_grafana_service(plan, service_name, image, port, command, build_file = None):
files = {
"/app": "configs",
}
if build_file != None:
files["/build"] = build_file

service = plan.add_service(
name = service_name,
config = ServiceConfig(
image = image,
files = files,
ports = {
"polkadot": PortSpec(port, transport_protocol = "TCP"),
},
public_ports = {
"polkadot": PortSpec(port, transport_protocol = "TCP"),
},
entrypoint = command,
),
)

return service

def launch_grafana(plan, args):
command = ["/run.sh"]
prometheus_grafana_service(plan, "grafana", "grafana/grafana-dev:10.3.0-147071", 3000, command, None)
114 changes: 114 additions & 0 deletions package_io/promethues.star
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
SERVICE_NAME = "prometheus"
PROMETHEUS_DEFAULT_SCRAPE_INTERVAL = "5s"
METRICS_INFO_ADDITIONAL_CONFIG_KEY = "config"
IMAGE_NAME = "prom/prometheus:latest"
HTTP_PORT_ID = "http"
HTTP_PORT_NUMBER = 9090
CONFIG_FILENAME = "prometheus-config.yml"
CONFIG_DIR_MOUNTPOINT_ON_PROMETHEUS = "/config"

shared_utils = import_module("./utils.star")

USED_PORTS = {
HTTP_PORT_ID: shared_utils.new_port_spec(
HTTP_PORT_NUMBER,
"TCP",
"http",
),
}

def launch_prometheus(
plan,
args,
service_details,
config_template):
template_data = new_config_template_data(
plan,
args,
service_details,
)
template_and_data = shared_utils.new_template_and_data(
config_template,
template_data,
)
template_and_data_by_rel_dest_filepath = {}
template_and_data_by_rel_dest_filepath[CONFIG_FILENAME] = template_and_data

config_files_artifact_name = plan.render_templates(
template_and_data_by_rel_dest_filepath,
"prometheus-config",
)

config = get_config(config_files_artifact_name)
prometheus_service = plan.add_service(SERVICE_NAME, config)

private_ip_address = prometheus_service.ip_address
prometheus_service_http_port = prometheus_service.ports[HTTP_PORT_ID].number

return "http://{0}:{1}".format(private_ip_address, prometheus_service_http_port)

def get_config(config_files_artifact_name):
config_file_path = shared_utils.path_join(
CONFIG_DIR_MOUNTPOINT_ON_PROMETHEUS,
shared_utils.path_base(CONFIG_FILENAME),
)
return ServiceConfig(
image = IMAGE_NAME,
ports = USED_PORTS,
public_ports = USED_PORTS,
files = {CONFIG_DIR_MOUNTPOINT_ON_PROMETHEUS: config_files_artifact_name},
cmd = [
"--config.file=" + config_file_path,
"--storage.tsdb.path=/prometheus",
"--storage.tsdb.retention.time=1d",
"--storage.tsdb.retention.size=512MB",
"--storage.tsdb.wal-compression",
"--web.console.libraries=/etc/prometheus/console_libraries",
"--web.console.templates=/etc/prometheus/consoles",
"--web.enable-lifecycle",
],
)

def new_config_template_data(plan, args, service_details):
metrics_jobs = []

relay_nodes = args["relaychain"]["nodes"]
for node in relay_nodes:
if node["prometheus"] == True:
endpoint = "{0}:{1}".format(service_details["relaychains"]["relay_service_{}".format(node["name"])].ip_address, service_details["relaychains"]["relay_service_{}".format(node["name"])].ports["prometheus"].number)

metrics_jobs.append(
new_metrics_job(
job_name = "relay_service_{}".format(node["name"]),
endpoint = endpoint,
scrape_interval = "5s",
),
)
plan.print(node["prometheus"])

for parachain in args["para"]:
for node in args["para"][parachain]["nodes"]:
if node["prometheus"] == True:
endpoint = "{0}:{1}".format(service_details["parachains"][parachain.lower()]["parachain_{}".format(node["name"])].ip_address, service_details["parachains"][parachain.lower()]["parachain_{}".format(node["name"])].ports["prometheus"].number)

metrics_jobs.append(
new_metrics_job(
job_name = "parachain_{}_{}".format(parachain, node["name"]),
endpoint = endpoint,
scrape_interval = "5s",
),
)

return {
"MetricsJobs": metrics_jobs,
}

def new_metrics_job(
job_name,
endpoint,
scrape_interval = PROMETHEUS_DEFAULT_SCRAPE_INTERVAL):
return {
"Name": job_name,
"Endpoint": endpoint,
"ScrapeInterval": scrape_interval,
}
16 changes: 16 additions & 0 deletions package_io/static_files/prometheus.yml.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: "prometheus"
scrape_interval: 5s
static_configs:
- targets: ["localhost:9090"]
{{- range $job := .MetricsJobs }}
- job_name: "{{ $job.Name }}"
{{- if $job.ScrapeInterval }}
scrape_interval: {{ $job.ScrapeInterval }}
{{- end }}
static_configs:
- targets: ['{{ $job.Endpoint }}']
{{- end }}
48 changes: 48 additions & 0 deletions package_io/utils.star
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
NOT_PROVIDED_APPLICATION_PROTOCOL = ""
NOT_PROVIDED_WAIT = "not-provided-wait"

def new_template_and_data(template, template_data_json):
return struct(template = template, data = template_data_json)

def path_join(*args):
joined_path = "/".join(args)
return joined_path.replace("//", "/")

def path_base(path):
split_path = path.split("/")
return split_path[-1]

def path_dir(path):
split_path = path.split("/")
if len(split_path) <= 1:
return "."
split_path = split_path[:-1]
return "/".join(split_path) or "/"

def new_port_spec(
number,
transport_protocol,
application_protocol = NOT_PROVIDED_APPLICATION_PROTOCOL,
wait = NOT_PROVIDED_WAIT):
if wait == NOT_PROVIDED_WAIT:
return PortSpec(
number = number,
transport_protocol = transport_protocol,
application_protocol = application_protocol,
)

return PortSpec(
number = number,
transport_protocol = transport_protocol,
application_protocol = application_protocol,
wait = wait,
)

def read_file_from_service(plan, service_name, filename):
output = plan.exec(
service_name = service_name,
recipe = ExecRecipe(
command = ["/bin/sh", "-c", "cat {} | tr -d '\n'".format(filename)],
),
)
return output["output"]
2 changes: 2 additions & 0 deletions parachain/node_setup.star
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ def run_testnet_node_with_entrypoint(plan, image, chain_name, execute_command):
image = image,
ports = {
"ws": PortSpec(9944, transport_protocol = "TCP"),
"prometheus": PortSpec(9615, transport_protocol = "TCP", application_protocol = "http"),
},
files = {
"/app": "configs",
Expand All @@ -18,6 +19,7 @@ def run_testnet_node_with_command(plan, image, chain_name, execute_command):
image = image,
ports = {
"ws": PortSpec(9944, transport_protocol = "TCP"),
"prometheus": PortSpec(9615, transport_protocol = "TCP", application_protocol = "http"),
},
files = {
"/app": "configs",
Expand Down
Loading

0 comments on commit 9a6d95b

Please sign in to comment.