Skip to content

Commit f713d9c

Browse files
shumkovktechmidasvivekgsharma
authored
feat: metric and load test nodes (#607)
* feat: load test nodes * fix: increase soft ulimit as well * feat: metrics provisioning * feat: deploy load test nodes with ansible * fix: ansible host to run on * chore: default to zero for LT nodes * chore: instance type change * feat: initial prometheus implementation in tf * refactor: rename prometheus to metrics nodes * chore: accomplish metrics and load test roles * chore: LT nodes should be AMD * chore: temp fixes * fix: duplicate prometheus port * chore: install latest protoc * fix: invalid .env * chore: redo insight API url * fix: change to http * fix: use dash_devnet_name var instead * chore: restore deploy platbook * modified_network_configs * chore: configure tenderdash mempool cache size * chore: update ouzo * chore: uncomment code * chore: added main_domain var to ansible initial config * chore: configure tenderdash mempool cache size * chore: update ouzo * chore: uncomment code * chore: linter fixes * chore: stop complaining linter * chore: set metrics/lt to always 1 * chore: fix CI * chore: more CI fixing * chore: final fix * chore: enable recheck * clean up * chore: remove mixerCount * feat: dynamic update of yml (#626) * feat: dynamic update of yml * feat: if less than * chore: fix debug + new line --------- Co-authored-by: ktechmidas <[email protected]> * chore: remove mixer/LT from generate * fix: linter * fix: linter * fix: more linter * fix: even more linting * fix: auto lint fix * fix: final lint fixing --------- Co-authored-by: ktechmidas <[email protected]> Co-authored-by: vivekgsharma <[email protected]>
1 parent 4f6a9d3 commit f713d9c

File tree

29 files changed

+655
-23
lines changed

29 files changed

+655
-23
lines changed

ansible/deploy.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,19 @@
7777
roles:
7878
- elastic_stack
7979

80+
- name: Setup load tester
81+
hosts: load_test
82+
become: true
83+
roles:
84+
- role: protobuf_compiler
85+
- role: load_tool
86+
87+
- name: Setup metrics
88+
hosts: metrics
89+
become: true
90+
roles:
91+
- role: metrics
92+
8093
- name: Set up miners
8194
hosts: miners
8295
become: true
@@ -231,6 +244,21 @@
231244
when: dash_network != "mainnet" and dash_network != "testnet"
232245
delegate_to: '{{ play_hosts | first }}'
233246

247+
248+
- name: Fund load tester nodes
249+
hosts: wallet_nodes
250+
become: true
251+
tasks:
252+
- name: Extract load tester addresses
253+
ansible.builtin.set_fact:
254+
load_tester_addresses: "{{ load_testers.values() | map(attribute='wallet.address') | list }}"
255+
256+
- name: Include funding for load testers
257+
ansible.builtin.include_tasks: ./roles/mn_fund_collateral/tasks/fund_collateral.yml
258+
vars:
259+
payment_targets: "{{ load_tester_addresses }}"
260+
amount: "{{ load_tester_wallet_amount }}"
261+
234262
# todo: partially working code causes errors in deploy, comment out for now and fix later
235263
# - name: Create governance proposals
236264
# hosts: wallet_nodes

ansible/group_vars/all

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,3 +174,8 @@ masternode_network_latency_max: 100
174174
# Dashmate stuff
175175
dashmate_home: /home/dashmate
176176
dashmate_logs_dir: '{{ dashmate_home }}/logs'
177+
178+
# Wallet funding amount for load testing nodes
179+
load_tester_wallet_amount: 100
180+
181+
prometheus_port: 36660

ansible/roles/dashmate/defaults/main.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ dashmate_platform_drive_tenderdash_p2p_max_packet_msg_payload_size: 10240
2323
dashmate_platform_drive_tenderdash_p2p_send_rate: 5120000
2424
dashmate_platform_drive_tenderdash_p2p_recv_rate: 5120000
2525
dashmate_platform_drive_tenderdash_mempool_size: 5000
26+
dashmate_platform_drive_tenderdash_mempool_cache_size: 10000
2627
dashmate_platform_drive_tenderdash_mempool_max_txs_bytes: 536870912 # 500Mb, default: 1073741824
2728
dashmate_platform_drive_tenderdash_rpc_max_open_connections: 900
2829
dashmate_platform_drive_tenderdash_consensus_peer_gossip_sleep_duration: "100ms"

ansible/roles/dashmate/tasks/main.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,8 @@
144144
mode: "0644"
145145
register: template_result
146146

147-
# We need to modify any config option to force dashmate render service configs
148147
- name: Render service configs
149-
ansible.builtin.command: "{{ dashmate_cmd }} config set dashmate.helper.api.enable true"
148+
ansible.builtin.command: "{{ dashmate_cmd }} config render"
150149
become: true
151150
become_user: dashmate
152151
args:

ansible/roles/dashmate/templates/dashmate.json.j2

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@
213213
"recvRate": {{dashmate_platform_drive_tenderdash_p2p_recv_rate}}
214214
},
215215
"mempool": {
216+
"cacheSize": {{dashmate_platform_drive_tenderdash_mempool_cache_size}},
216217
"size": {{dashmate_platform_drive_tenderdash_mempool_size}},
217218
"maxTxsBytes": {{dashmate_platform_drive_tenderdash_mempool_max_txs_bytes}}
218219
},
@@ -228,7 +229,7 @@
228229
"metrics": {
229230
"enabled": true,
230231
"host": "{{ private_ip }}",
231-
"port": 36660
232+
"port": {{ prometheus_port }}
232233
},
233234
"consensus": {
234235
"createEmptyBlocks": true,
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
---
2+
3+
- name: Increase nofile limit
4+
community.general.pam_limits:
5+
domain: '*'
6+
limit_type: "-"
7+
limit_item: nofile
8+
value: 60240
9+
10+
- name: Install system dependencies
11+
ansible.builtin.package:
12+
name:
13+
- cmake
14+
- clang
15+
- build-essential
16+
- libc-dev
17+
- libssl-dev
18+
- pkg-config
19+
state: present
20+
when: dashmate_platform_enable
21+
22+
- name: Download Rustup
23+
ansible.builtin.get_url:
24+
url: https://sh.rustup.rs
25+
dest: '/home/ubuntu/rustup.sh'
26+
owner: 'ubuntu'
27+
group: 'ubuntu'
28+
mode: '0755'
29+
register: rustup
30+
31+
- name: Install Rust
32+
ansible.builtin.command:
33+
cmd: "/home/ubuntu/rustup.sh -y"
34+
become: true
35+
become_user: ubuntu
36+
when: rustup.changed # noqa: no-handler
37+
changed_when: true
38+
39+
- name: Clone platform
40+
ansible.builtin.git:
41+
repo: 'https://github.com/dashpay/platform.git'
42+
dest: /home/ubuntu/load-test/platform
43+
version: '{{ dashmate_branch }}'
44+
become: true
45+
become_user: ubuntu
46+
47+
- name: Clone explorer
48+
ansible.builtin.git:
49+
repo: 'https://github.com/dashpay/rs-platform-explorer.git'
50+
dest: /home/ubuntu/load-test/rs-platform-explorer
51+
version: load-test
52+
become: true
53+
become_user: ubuntu
54+
55+
- name: Create .env file
56+
ansible.builtin.template:
57+
src: .env.j2
58+
dest: /home/ubuntu/load-test/rs-platform-explorer/.env
59+
owner: ubuntu
60+
group: ubuntu
61+
mode: "0644"
62+
become: true
63+
become_user: ubuntu
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Comma-separated list of full URLs to DAPI nodes for the explorer to connect to.
2+
EXPLORER_DAPI_ADDRESSES={%- for hp_name in groups["hp_masternodes"] +%}http://{{ hostvars[hp_name]["public_ip"] }}:1443{%- if not loop.last %},{% endif %}{% endfor %}
3+
4+
# The hostname or IP address of Dash Core RPC interface.
5+
EXPLORER_CORE_HOST={{ hostvars[groups["wallet_nodes"][0]]["private_ip"] }}
6+
7+
# EXPLORER_CORE_RPC_PORT
8+
# The port number on which Dash Core RPC is listening.
9+
EXPLORER_CORE_RPC_PORT={{ dashd_rpc_port }}
10+
11+
# The username for authentication with Dash Core RPC
12+
EXPLORER_CORE_RPC_USER={{ dashd_rpc_user }}
13+
14+
# The password for authentication with Dash Core RPC
15+
EXPLORER_CORE_RPC_PASSWORD={{ dashd_rpc_password }}
16+
17+
# Testnet Insight API URL
18+
EXPLORER_INSIGHT_API_URL=http://insight.{{ dash_devnet_name }}.{{ main_domain }}:{{ insight_port }}/insight-api
19+
20+
# Network name
21+
EXPLORER_NETWORK={{ dash_network }}
22+
23+
# TOOD: Create and fund a wallet
24+
EXPLORER_WALLET_PRIVATE_KEY={{ load_testers[inventory_hostname]["wallet"]["private_key"] }}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
3+
metrics_user: 'ubuntu'
4+
metrics_path: '/home/{{ metrics_user }}/metrics'
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
global
2+
log stdout format raw local0
3+
4+
defaults
5+
log global
6+
option httplog
7+
option dontlognull
8+
9+
10+
frontend http_front
11+
id 1
12+
bind *:80
13+
mode http
14+
15+
acl prometheus_path path_beg /prometheus
16+
acl grafana_path path_beg /grafana
17+
18+
19+
use_backend prometheus if prometheus_path
20+
use_backend grafana if grafana_path
21+
22+
backend prometheus
23+
# http-request set-path %[path,regsub(^/prometheus,,g)]
24+
server prometheus_server prometheus:9090
25+
mode http
26+
27+
backend grafana
28+
# http-request set-path %[path,regsub(^/grafana,,g)]
29+
server grafana_server grafana:3000
30+
mode http
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
---
2+
groups:
3+
- name: Tenderdash chain
4+
rules:
5+
- alert: ChainHalt
6+
expr: rate(drive_tenderdash_consensus_latest_block_height[10m]) == 0
7+
for: 10m
8+
labels:
9+
severity: major
10+
service: tenderdash
11+
annotations:
12+
description: 'Chain appears to be halted'
13+
14+
- alert: RoundTooHigh
15+
expr: 'drive_tenderdash_consensus_rounds > 3'
16+
for: 1m
17+
labels:
18+
severity: minor
19+
service: tenderdash
20+
annotations:
21+
description: 'Voting round too high'

ansible/roles/metrics/tasks/main.yml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
---
2+
3+
- name: Create a directories for the project
4+
ansible.builtin.file:
5+
path: '{{ metrics_path }}/{{ item }}'
6+
state: directory
7+
recurse: true
8+
owner: '{{ metrics_user }}'
9+
group: '{{ metrics_user }}'
10+
mode: '0755'
11+
loop:
12+
- 'prometheus/config'
13+
- 'grafana'
14+
- 'haproxy'
15+
16+
- name: Copy haproxy configs and prometheus rules
17+
ansible.builtin.copy:
18+
src: '{{ item }}'
19+
dest: '{{ metrics_path }}/{{ item }}'
20+
owner: '{{ metrics_user }}'
21+
group: '{{ metrics_user }}'
22+
mode: '0644'
23+
loop:
24+
- haproxy/haproxy.cfg
25+
- prometheus/rules.yml
26+
27+
- name: Render docker compose configs
28+
ansible.builtin.template:
29+
src: 'docker-compose.yml.j2'
30+
dest: '{{ metrics_path }}/docker-compose.yml'
31+
owner: '{{ metrics_user }}'
32+
group: '{{ metrics_user }}'
33+
mode: '0644'
34+
35+
- name: Render prometheus configs
36+
ansible.builtin.template:
37+
src: 'prometheus.yml.j2'
38+
dest: '{{ metrics_path }}/prometheus/config/prometheus.yml'
39+
owner: '{{ metrics_user }}'
40+
group: '{{ metrics_user }}'
41+
mode: '0644'
42+
43+
- name: Start metrics
44+
community.docker.docker_compose:
45+
project_src: '{{ metrics_path }}'
46+
restarted: true
47+
state: present
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
version: '3'
2+
services:
3+
haproxy:
4+
image: haproxy:latest
5+
ports:
6+
- "80:80"
7+
volumes:
8+
- ./haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg
9+
10+
prometheus:
11+
user: root
12+
image: prom/prometheus:latest
13+
command:
14+
- '--config.file=/etc/prometheus/prometheus.yml'
15+
- '--web.external-url=http://{{ public_ip }}/prometheus'
16+
- '--log.level=debug'
17+
volumes:
18+
- ./prometheus/config:/etc/prometheus
19+
- /mnt/prometheus:/prometheus
20+
expose:
21+
- 9090
22+
23+
grafana:
24+
image: grafana/grafana:latest
25+
user: root
26+
volumes:
27+
- ./grafana/data:/var/lib/grafana # TODO: Must be mounted on a volume or mnt?
28+
environment:
29+
- GF_SERVER_ROOT_URL=/grafana
30+
- GF_SERVER_SERVE_FROM_SUB_PATH=true
31+
- GF_SERVER_ROUTER_LOGGING=true
32+
expose:
33+
- 3000
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
---
2+
# my global config
3+
global:
4+
scrape_interval: 5s # Set the scrape interval to every 5 seconds. Default is every 1 minute.
5+
evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
6+
# scrape_timeout is set to 3s; global default is 10s.
7+
scrape_timeout: 3s
8+
9+
# Alertmanager configuration
10+
alerting:
11+
alertmanagers:
12+
- static_configs:
13+
- targets:
14+
# - alertmanager:9093
15+
16+
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
17+
rule_files:
18+
- "rules.yml"
19+
# - "first_rules.yml"
20+
# - "second_rules.yml"
21+
22+
# A scrape configuration containing exactly one endpoint to scrape:
23+
# Here it's Prometheus itself.
24+
scrape_configs:
25+
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
26+
- job_name: "prometheus"
27+
# metrics_path defaults to '/metrics'
28+
# scheme defaults to 'http'.
29+
metrics_path: /prometheus/metrics
30+
static_configs:
31+
- targets: ["localhost:9090"]
32+
33+
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
34+
- job_name: "tenderdash"
35+
36+
# metrics_path defaults to '/metrics'
37+
# scheme defaults to 'http'.
38+
39+
static_configs:
40+
{% for hp_name in groups["hp_masternodes"] %}
41+
- targets: ["{{ hostvars[hp_name]['private_ip'] }}:{{ prometheus_port }}"]
42+
labels:
43+
node: "{{ hp_name }}"
44+
{% endfor %}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
protoc_version: "25.2"
2+
protoc_dest_path: "/opt/protoc"
3+
protoc_bin_path: "/usr/bin/protoc"
4+
protoc_zip_file_name: "protoc-{{ protoc_version }}-linux-{{ 'aarch_64' if ansible_architecture == 'aarch64' else 'x86_64' }}.zip"
5+
protoc_zip_url: "https://github.com/protocolbuffers/protobuf/releases/download/v{{ protoc_version }}/{{ protoc_zip_file_name }}"
6+
protoc_zip_path: "/tmp"
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
- name: Download protoc zip file
2+
ansible.builtin.get_url:
3+
url: "{{ protoc_zip_url }}"
4+
dest: "/tmp/"
5+
mode: '0644'
6+
7+
- name: Ensure destination directory exists
8+
ansible.builtin.file:
9+
path: "{{ protoc_dest_path }}"
10+
state: directory
11+
mode: '0755'
12+
13+
- name: Unzip protoc to the destination
14+
ansible.builtin.unarchive:
15+
src: "{{ protoc_zip_path }}/{{ protoc_zip_file_name }}"
16+
dest: "{{ protoc_dest_path }}"
17+
remote_src: true
18+
# TODO: Create an empty file with version and then check if it's exists
19+
# creates: "{{ protoc_dest_path }}/{{ protoc_version }}-installed"
20+
mode: '755'
21+
22+
- name: Create symlink for protoc
23+
ansible.builtin.file:
24+
src: "{{ protoc_dest_path }}/bin/protoc"
25+
dest: "{{ protoc_bin_path }}"
26+
state: link
27+
force: true

0 commit comments

Comments
 (0)