Skip to content

Repository files navigation

🛠️ Monitoring Gnoland Validators

This repository provides lightweight tools to monitor the Gno.land blockchain and its validators.

🧩 Architecture Overview:

Architecture Overview

Two services are available:

  • GovDAO – Detect news proposal and status (ACCEPTED / REFUSED / IN PROGRESS).

  • Validator Alerting – Monitors the entire validator set, calculates participation rates and sends Discord/Slack/Telegram alerts when needed. Also exposes Prometheus metrics.


📑 Summary


🛠️ Setup

Requirements

1.Copy the configuration template and edit it:

cd backend 
cp config.yaml.template config.yaml 
nano config.yaml

2.Customize parameters as needed. For example:

backend_port: "8989"
allow_origin: "http://localhost:3000"
rpc_endpoint: "https://rpc.test9.testnets.gno.land"
metrics_port: 8888
gnoweb: "https://test9.testnets.gno.land"
graphql: "indexer.test9.testnets.gno.land/graphql/query"
clerk_secret_key: "sk_test...." #change me
dev_mode: false # Set to true for local development without Clerk auth
token_telegram_validator: ""
token_telegram_govdao: ""

3.Start the backend:

docker compose up -d 

🧪 Local devnet (end-to-end testing)

The gnoland-test/ directory ships a self-contained, Docker-based 3-validator Gno.land devnet used to exercise every gnomonitoring feature (participation tracking, WARNING/CRITICAL/RESOLVED alerts, chain-stagnation and RPC-error alerts, the GovDAO watcher, Prometheus metrics) end-to-end before merging.

Nothing secret or generated is committed — keys, genesis, .env and the gnokey keybase are all regenerated from scratch by bootstrap.sh on each setup (addresses differ every run, which is fine: everything is derived from the same fresh keys). Requires a local clone of the gno repo to build the images.

cd gnoland-test
make full-reinit     # build images, regenerate keys/genesis, start the chain
make scenario1       # onboard a 4th validator via a GovDAO proposal
make help            # full list of lifecycle + test-scenario targets

Scenarios cover validator downtime (scenario2), chain halt/stagnation (scenario3), total RPC outage (scenario4), a rejected GovDAO proposal (scenario5) and alert resend dedup (scenario-mute); make clean-all nukes all generated state for a fully fresh run. See gnoland-test/README.md for the full guide, the per-scenario assertions, and how to point the backend at the devnet.


🌍 Multi-Chain Support

Gnomonitoring now supports monitoring multiple Gno.land blockchains simultaneously from a single deployment. Each chain runs independently while sharing the same database and REST API.

Overview

Instead of deploying separate instances per chain, you can configure multiple chains in one config.yaml. Each chain:

  • Has its own RPC endpoint, GraphQL indexer, and Gnoweb UI
  • Maintains independent validator monitoring loops
  • Stores data isolated by chain ID in PostgreSQL
  • Sends alerts and reports scoped to its validators
  • Works seamlessly with webhooks, Telegram bots, and Prometheus metrics

Configuration

Edit config.yaml to define your chains:

backend_port: "8989"
metrics_port: 8888
dev_mode: true
clerk_secret_key: "sk_test...."
token_telegram_validator: ""
token_telegram_govdao: ""

# Default chain used when no ?chain= query parameter is supplied
default_chain: "test12"

# Multi-chain configuration
chains:
  test12:
    rpc_endpoint: "https://rpc.test12.testnets.gno.land"
    graphql: "https://indexer.test12.testnets.gno.land/graphql/query"
    gnoweb: "https://test12.testnets.gno.land"
    enabled: true

  gnoland1:
    rpc_endpoint: "https://rpc.betanet.testnets.gno.land"
    graphql: "https://indexer.betanet.testnets.gno.land/graphql/query"
    gnoweb: "https://betanet.testnets.gno.land"
    enabled: true

  test11:
    rpc_endpoint: "https://rpc.test11.testnets.gno.land"
    graphql: "https://indexer.test11.testnets.gno.land/graphql/query"
    gnoweb: "https://test11.testnets.gno.land"
    enabled: false  # Disable by setting to false

Key points:

  • Each chain gets a unique identifier (e.g., test12, gnoland1)
  • Set enabled: true to monitor a chain
  • Set enabled: false to disable a chain without removing it
  • default_chain is used when clients don't specify a chain parameter
  • All disabled chains are ignored during startup

API Endpoints with Chain Parameter

Most API endpoints accept an optional ?chain=<chain_id> query parameter to scope results to a specific chain. If omitted, the default chain is used.

Examples:

# Get participation rate for default chain (test12)
curl 'http://localhost:8989/Participation?period=current_month'

# Get participation rate for specific chain
curl 'http://localhost:8989/Participation?chain=gnoland1&period=current_month'

# Get uptime for test12 chain
curl 'http://localhost:8989/uptime?chain=test12'

# Get block height for gnoland1 chain
curl 'http://localhost:8989/block_height?chain=gnoland1'

# Get missing blocks for test11 chain
curl 'http://localhost:8989/missing_block?chain=test11'

Webhook Management with Chain Scoping

Webhooks can be created for a specific chain or globally to receive alerts from all chains.

Create a webhook for a specific chain:

curl -L -X POST 'http://localhost:8989/webhooks/validator?chain=gnoland1' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <Clerk_Token>' \
  -d '{
    "URL": "https://discord.com/api/webhooks/...",
    "Type": "discord",
    "Description": "GnoLand1 Alerts"
  }'

Create a global webhook (all chains):

curl -L -X POST 'http://localhost:8989/webhooks/validator' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <Clerk_Token>' \
  -d '{
    "URL": "https://discord.com/api/webhooks/...",
    "Type": "discord",
    "Description": "All Chains Alerts"
  }'

Alert messages include chain labels:

When an alert is sent, it includes the chain identifier:

[test12] WARNING: Validator gnocore-val-01 missed 5 blocks (#12345-#12349)
[gnoland1] CRITICAL: Validator onbloc-val-02 missed 30 blocks (#67890-#67919)

Telegram Bot Multi-Chain Support

The Telegram validator bot includes commands to switch between chains on a per-chat basis.

New commands:

  • /chain - Display current active chain and list all enabled chains
Current chain: test12

Available chains:
- test12
- gnoland1
- test11

Use /setchain <chain> to switch chains.
  • /setchain <chain_id> - Switch the active chain for this chat
/setchain gnoland1
→ Active chain set to gnoland1

/setchain
→ Using default chain: test12

Updated commands (all work per-chain context):

  • /status - Get validator participation rate on active chain
  • /uptime - Get validator uptime on active chain
  • /tx_contrib - Get validator transaction contribution on active chain
  • /missing - List validators with missed blocks on active chain
  • /subscribe on <address> - Subscribe to validator alerts on active chain
  • /subscribe off <address> - Unsubscribe from validator alerts on active chain
  • /subscribe list - Show your subscriptions on active chain

Hourly reports per chain:

When you activate /report, you receive daily reports for your currently active chain. Switch chains with /setchain and activate reports on each chain independently.

Prometheus Metrics with Chain Labels

All Prometheus metrics include a chain label to distinguish data by chain:

gnoland_missed_blocks{chain="test12",moniker="gnocore-val-01",validator_address="g1ek7ftha29qv4ahtv7jzpc0d57lqy7ynzklht7t"} 5
gnoland_missed_blocks{chain="gnoland1",moniker="onbloc-val-02",validator_address="g1j306jcl4qyhgjw78shl3ajp88vmvdcf7m7ntm2"} 12

gnoland_validator_participation_rate{chain="test12",moniker="gnocore-val-01",validator_address="g1ek7ftha29qv4ahtv7jzpc0d57lqy7ynzklht7t"} 99.98
gnoland_validator_participation_rate{chain="gnoland1",moniker="onbloc-val-02",validator_address="g1j306jcl4qyhgjw78shl3ajp88vmvdcf7m7ntm2"} 98.5

Use Prometheus relabeling or Grafana to group metrics by chain:

metric_relabel_configs:
  - source_labels: [chain]
    regex: (.+)
    action: keep

Known Limitations

  1. GovDAO Bot Single-Chain: The GovDAO bot monitors proposals only on the default_chain. To monitor proposals on multiple chains, deploy separate instances.

  2. Prometheus Memory: Each (chain × validator × metric) creates a new time series. With 5 chains and 100 validators, expect ~1500 metric series. Monitor Prometheus memory usage; archive old data if needed.

  3. Storage Scaling: Data is stored in PostgreSQL. Raw per-block participation is bounded by raw_retention_days (default 7) and rolled up into daily aggregates, so the dataset stays bounded as chains progress. For very large multi-chain deployments, monitor table/index growth and tune retention accordingly.


🔗 Webhook Management (Discord / Slack)

✚ Add webhook URL:

curl -L -X POST '127.0.0.7:8989/webhooks/[govdao | validator]' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer Clerk_Token ' \
-d '{
     "URL": "https://discord.com/api/webhooks/.....",
    "Type": "discord",
    "Description":"Samourai"
  }'

☰ List webhook URL:

curl -L -X GET '127.0.0.7:8989/webhooks/[govdao | validator]' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer Clerk_Token' 

❌ Delete webhook URL:

curl -L -X DELETE '127.0.0.7:8989/webhooks/[govdao | validator]?id=2' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer Clerk_Token' 

🔄 Update webhook URL:

curl -L -X PUT '127.0.0.7:8989/webhooks/[govdao | validator]' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer Clerk_Token' 
-d '{
    "ID": 3,
   
    "URL": "https://discord.com/api/...",
    "Type": "discord",
    "Description": "Samourai"
}

📢 ALERTING

Sends alerts (Discord/Slack) when:

  • Rpc is down
  • The blockchain is stuck on the same block for more than 2 minutes.

Alert example

  • A new validator joins the network.

News Validators

  • A validator's missed block :
    • WARNING if a validator missed 5 blocks.
    • CRITICAL if a validator missed more of 30 blocks
  • Send Resolve Alert.

Alert example

  • Send Daily Report:

Discord alert daily


📝 Expose Metrics from API REST

The disponible period for metrics:

  • current_week
  • current_month
  • current_year
  • all_time
Participate Rate

The participation rate represents the percentage of blocks in which a validator successfully participated during a given time period.

curl -X GET '127.0.0.1:8989/Participation?period=all_time'

Response:

[{"addr":"g1ek7ftha29qv4ahtv7jzpc0d57lqy7ynzklht7t","moniker":"gnocore-val-01","participationRate":100},
  {"addr":"g1j306jcl4qyhgjw78shl3ajp88vmvdcf7m7ntm2","moniker":"onbloc-val-02","participationRate":100}]
Missing Block Metrics

The Missing Block metric measures the total number of blocks that a validator failed to participate in during a given period

curl -X GET '127.0.0.1:8989/missing_block?period=all_time''

Response:

[{"moniker":"gnocore-val-01","addr":"g1ek7ftha29qv4ahtv7jzpc0d57lqy7ynzklht7t","missingBlock":1},
{"moniker":"onbloc-val-02","addr":"g1j306jcl4qyhgjw78shl3ajp88vmvdcf7m7ntm2","missingBlock":1},
{"moniker":"onbloc-val-01","addr":"g1kntcjkfplj0z44phajajwqkx5q4ry5yaft5q2h","missingBlock":1}...
Tx Contrib Metrics

The Tx Contribution metric measures how much a validator has contributed to the total number of transactions processed across all validators during a specific period.

curl -X GET '127.0.0.1:8989/tx_contrib?period=all_time'

Response:

[{"moniker":"gnocore-val-01","addr":"g1ek7ftha29qv4ahtv7jzpc0d57lqy7ynzklht7t","txContrib":14.4},
{"moniker":"onbloc-val-02","addr":"g1j306jcl4qyhgjw78shl3ajp88vmvdcf7m7ntm2","txContrib":22.9},...
Lastest incidents

The Latest Incidents metric retrieves the most recent critical or warning events (alerts) detected for validators within a specific time period.

curl -X GET '127.0.0.1:8989/latest_incidents?period=all_time'

Response:

[{"moniker":"onbloc-val-02","addr":"g1j306jcl4qyhgjw78shl3ajp88vmvdcf7m7ntm2","level":"CRITICAL","startHeight":78811,"endHeight":78840,"msg":"","sentAt":"2025-10-20T14:40:45.452216011-03:00"},
{"moniker":"all","addr":"all","level":"CRITICAL","startHeight":78840,"endHeight":78840,"msg":"🚨 CRITICAL : Blockchain stuck at height 78840 since 18 Oct 25 16:29 UTC (121h33m45s ago)","sentAt":"2025-10-23T15:03:10.282235678-03:00"},
{"moniker":"onbloc-val-02","addr":"g1j306jcl4qyhgjw78shl3ajp88vmvdcf7m7ntm2","level":"WARNING","startHeight":78834,"endHeight":78838,"msg":"","sentAt":"2025-10-22T13:28:53.018836743-03:00"},
Uptime Metrics

Validator Uptime represents the percentage of the last 500 blocks in which a validator was active and participated successfully.

curl -X GET 'localhost:8989/uptime'

Response:

[{"moniker":"onbloc-val-02","addr":"g1j306jcl4qyhgjw78shl3ajp88vmvdcf7m7ntm2","uptime":94},
{"moniker":"gnocore-val-01","addr":"g1ek7ftha29qv4ahtv7jzpc0d57lqy7ynzklht7t","uptime":100}]
Operation time Metrics

Operation Time represents the number of days between a validator’s last successful participation and its most recent downtime.

curl -X GET ‘localhost:8989/operation_time’

Response:

[{"moniker":"gnocore-val-01",
"addr":"g1ek7ftha29qv4ahtv7jzpc0d57lqy7ynzklht7t",
"lastDownDate":"2025-10-14 08:00:00+00:00",
"lastUpDate":"2025-10-18 16:29:24.242186417+00:00","operationTime":4.4}....
First Seen Metrics

Returns the first block date at which each validator was observed participating.

curl -X GET ‘localhost:8989/first_seen’

Response:

[{"addr":"g1ek7ftha29qv4ahtv7jzpc0d57lqy7ynzklht7t","moniker":"gnocore-val-01","firstSeen":"2025-09-01 12:00:00+00:00"},
{"addr":"g1j306jcl4qyhgjw78shl3ajp88vmvdcf7m7ntm2","moniker":"onbloc-val-02","firstSeen":"2025-09-02 08:30:00+00:00"}]
Block Height

Returns the last block height stored in the database.

curl -X GET ‘localhost:8989/block_height’

Response:

{"last_stored": 123456}
Info

Returns the configured Gnoweb and RPC endpoint URLs.

curl -X GET ‘localhost:8989/info’

Response:

{"gnoweb":"https://test9.testnets.gno.land","rpc":"https://rpc.test9.testnets.gno.land"}
Addr Moniker

Returns the moniker for a given validator address.

curl -X GET ‘localhost:8989/addr_moniker?addr=g1ek7ftha29qv4ahtv7jzpc0d57lqy7ynzklht7t’

Response:

{"addr":"g1ek7ftha29qv4ahtv7jzpc0d57lqy7ynzklht7t","moniker":"gnocore-val-01"}
Validator Health Report

Per-validator health score (0–100), tier, and alert metrics over four rolling periods. Always available, no authentication required, same as the other public dashboard endpoints above.

GET /api/reports/validators?chain=<chainID>[&addr=<validatorAddr>]
  • chain (required) — must be one of the enabled chains in config.yaml. An unknown chain returns HTTP 400.
  • addr (optional) — filter to a single validator address. Omit to get every validator currently in the valset.
# Every validator currently in the valset for a chain
curl -X GET 'localhost:8989/api/reports/validators?chain=test12'

# A single validator
curl -X GET 'localhost:8989/api/reports/validators?chain=test12&addr=g1ek7ftha29qv4ahtv7jzpc0d57lqy7ynzklht7t'

Response — a JSON array, one object per validator:

[{"addr":"g1ek7ftha29qv4ahtv7jzpc0d57lqy7ynzklht7t","moniker":"gnocore-val-01","days_since_last_alert":3,
  "periods":{"current_month":{"score":91,"tier":"Excellent","sign_rate":100,"proposer_reliability":88.0,
  "voting_power":1000,"critical_count":1,"warning_count":0,"incident_count":1,"incident_rate_per_week":0.47,"downtime_blocks":30,"missed_blocks":0}, "...": "..."}}]

Top-level fields:

  • addr / moniker — validator address and display name.
  • days_since_last_alert — global (not per-period): full days since the validator's most recent WARNING/CRITICAL alert, null if it has never alerted.
  • periods — an object with all four keys always present: last_24h, current_week, current_month, current_year.

Each period object carries:

  • score (0–100) / tier (Excellent ≥85, Good ≥60, Watch ≥30, Critical <30)
  • sign_rate — % of expected blocks actually signed this period (the base of the score)
  • proposer_reliability — % of expected block proposals actually made; null when the validator's expected proposal count is too low to be a meaningful signal (dropped from the score in that case)
  • voting_power — latest snapshot, refreshed every ~5 minutes
  • critical_count / warning_count — raw alert counts for the period (includes resends of the same ongoing incident)
  • incident_count — number of distinct incidents (consecutive alerts not separated by a RESOLVED collapse into one — an outage that escalates from WARNING to CRITICAL is still one incident). Unlike the raw counts above, this isn't inflated by resends, so it's the better signal for a validator that flaps on and off repeatedly versus one with a single long outage.
  • incident_rate_per_weekincident_count normalized by elapsed days in the period (floor 1 day) and expressed as an incidents/week-equivalent rate. This, not the raw count, is what actually drives the frequency penalty — the same incident_count is penalized less when it's spread over current_month/current_year than when it's concentrated in last_24h.
  • downtime_blocks — blocks lost to CRITICAL outages
  • missed_blocks — blocks not signed this period (display-only, already reflected in sign_rate)

Valset membership: a validator that has left the valset (no current voting power) is excluded from the report entirely, across every period, even when targeted directly via addr — it doesn't linger with a decaying score. Membership is re-checked every ~5 minutes; a validator that just left may still appear for up to that window. On a chain that hasn't captured a single voting-power snapshot yet (e.g. right after being enabled), the filter is skipped entirely and every validator is shown — "no VP data yet" is never treated the same as "everyone left."

How the score is calculated (0–100):

  1. Availability base100 × signed_blocks / total_blocks for the period.
  2. Proposer reliability — how often the validator proposed a block versus its expected share by voting power; dropped when too few proposals are expected to be a meaningful signal.
  3. Presence — a weighted blend of the two above (default weights: 0.8 signing / 0.2 proposing).
  4. Incident penalties — points deducted per CRITICAL alert, per WARNING alert, per incident/week-equivalent rate (see incident_rate_per_week above), and per block of CRITICAL downtime, each capped. Defaults: −6/critical (cap 60), −2/warning (cap 20), −3/7 (≈−0.43) per incident/week-equivalent (cap 30), −1 per 500 downtime blocks (cap 20).
  5. Voting-power severity — the total penalty is scaled up for higher-stake validators (up to ×1.5 for the top-VP validator by default), since their downtime matters more to consensus.

Final score: clamp(presence − total_penalty, 0, 100), mapped to a tier as above. All weights, caps, and the presence blend ratio are tunable via admin_config keys (report_score_*) without a redeploy.

Incident frequency (incident_count / incident_rate_per_week) and what it changes: critical_count/warning_count count every alert row, including resends of the same ongoing outage — a validator down for days can rack up several CRITICAL rows for one continuous failure. incident_count collapses those into distinct incidents instead (an escalation from WARNING to CRITICAL with no recovery in between is still one incident), so a validator that flaps in and out repeatedly is penalized more than one with a single long outage of comparable total downtime, even though the raw counts and downtime_blocks look similar between the two.

The penalty itself is driven by incident_rate_per_week, not the raw incident_count: the count is divided by elapsed days in the period (floored at 1 day) and expressed as an incidents/week-equivalent rate, so the same incident_count is penalized less the more it's diluted across a longer period. last_24h always has exactly 1 elapsed day, so its rate equals incident_count × 7 — deliberately calibrated (default report_score_freq_weight = 3/7 ≈ 0.43) so that last_24h scoring is unchanged from the pre-rate-normalization behavior, while current_month/current_year taper the same incident count down in proportion to how spread out it is. Scored as −report_score_freq_weight per incident/week-equivalent (default ≈0.43), capped at report_score_freq_cap (default 30).

Does the score improve over time? Depends on the period:

  • last_24h is a true rolling window — an incident from 25 hours ago automatically falls out of it. This is the only period that self-heals continuously, and the fastest signal of recent health.
  • current_week / current_month / current_year are calendar windows (Monday–Monday, 1st–1st, Jan 1–Jan 1), not rolling ones. sign_rate is cumulative from the period's start to now, so consistent good behavior dilutes a past bad stretch as more blocks accumulate — and the same is now true of the incident penalty: incident_count itself never decreases within the period, but incident_rate_per_week does, since its denominator (elapsed days) keeps growing even with no new incidents. critical_count/warning_count penalties don't benefit from this dilution — they're flat counts, only reset at the next calendar boundary.
  • current_year is the slowest to recover: an incident in January still weighs on the number for the rest of the year, until the next January 1 reset. Use last_24h/current_week to judge recent behavior and current_year for long-term track record — they're deliberately different signals, not the same number at different resolutions.

👤 User Management (protected)

All endpoints below require a valid Clerk Authorization: Bearer <token> header (or X-Debug-UserID in dev mode).

Create user:

curl -X POST ‘localhost:8989/users’ \
  -H ‘Authorization: Bearer <token>’ \
  -H ‘Content-Type: application/json’ \
  -d ‘{"name":"Alice","email":"alice@example.com"}’

Get user:

curl -X GET ‘localhost:8989/users?user_id=<user_id>’ \
  -H ‘Authorization: Bearer <token>

Update user:

curl -X PUT ‘localhost:8989/users’ \
  -H ‘Authorization: Bearer <token>’ \
  -H ‘Content-Type: application/json’ \
  -d ‘{"name":"Alice Updated","email":"alice2@example.com"}’

Delete user:

curl -X DELETE ‘localhost:8989/users’ \
  -H ‘Authorization: Bearer <token>

🔔 Alert Contacts (protected)

Manage contacts that receive mention tags in CRITICAL alerts.

List contacts:

curl -X GET ‘localhost:8989/alert-contacts’ \
  -H ‘Authorization: Bearer <token>

Add contact:

curl -X POST ‘localhost:8989/alert-contacts’ \
  -H ‘Authorization: Bearer <token>’ \
  -H ‘Content-Type: application/json’ \
  -d ‘{"moniker":"gnocore-val-01","namecontact":"Bob","mention_tag":"123456789","id_webhook":1}’

Update contact:

curl -X PUT ‘localhost:8989/alert-contacts’ \
  -H ‘Authorization: Bearer <token>’ \
  -H ‘Content-Type: application/json’ \
  -d ‘{"id":1,"moniker":"gnocore-val-01","namecontact":"Bob","mention_tag":"987654321","id_webhook":1}’

Delete contact:

curl -X DELETE ‘localhost:8989/alert-contacts?id=1’ \
  -H ‘Authorization: Bearer <token>

🕘 Daily Report Schedule (protected)

Configure the hour at which the daily report is sent.

Get current schedule:

curl -X GET ‘localhost:8989/usersH’ \
  -H ‘Authorization: Bearer <token>

Response:

{"user_id":"...","daily_report_hour":9,"daily_report_minute":0,"timezone":"Europe/Paris"}

Update schedule:

curl -X PUT ‘localhost:8989/usersH’ \
  -H ‘Authorization: Bearer <token>’ \
  -H ‘Content-Type: application/json’ \
  -d ‘{"hour":8,"minute":30,"timezone":"America/New_York"}’

📈 Prometheus Metrics

Metrics are exposed at http://localhost:8888/metrics. All metrics include chain labels to support multi-chain deployments.

Validator Metrics (per-validator, updated every 5 minutes):

  • gnoland_validator_uptime — Participation rate (%) over last 500 blocks
  • gnoland_validator_operation_time — Days since validator's last downtime event
  • gnoland_validator_tx_contribution — Transaction contribution (%) in current month
  • gnoland_validator_missing_blocks_month — Blocks missed in current month
  • gnoland_validator_first_seen_unix — Unix timestamp of first participation

Chain Metrics (chain-level aggregates):

  • gnoland_chain_active_validators — Number of active validators (last 100 blocks)
  • gnoland_chain_avg_participation_rate — Average participation rate (%) across chain
  • gnoland_chain_current_height — Current blockchain height

Alert Metrics (active and cumulative alerts):

  • gnoland_active_alerts — Currently unresolved alerts by severity (CRITICAL/WARNING)
  • gnoland_alerts_total — Cumulative alert count by severity

Label examples:

gnoland_validator_uptime{chain="test12",validator_address="g1ek7ftha29qv4ahtv7jzpc0d57lqy7ynzklht7t",moniker="gnocore-val-01"} 99.5
gnoland_chain_active_validators{chain="test12"} 125
gnoland_active_alerts{chain="test12",level="CRITICAL"} 2

PromQL query examples:

# Uptime for all validators on test12 chain
gnoland_validator_uptime{chain="test12"}

# Validators with uptime below 95%
gnoland_validator_uptime{chain="test12"} < 95

# Total active alerts across all chains
sum(gnoland_active_alerts)

# Average participation rate by chain
avg by (chain) (gnoland_chain_avg_participation_rate)

Performance notes:

Metrics are computed every 5 minutes with a 2-minute timeout per chain to prevent slowdowns on heavily-loaded networks. Validator metrics use a 30-day rolling window (not full history) to maintain query performance.


✉️ Telegram Bot

🌐 Govdao bot

/status — list recent GovDAO proposals ⮑ Params: limit (optional, default: 10)

/status limit=5

/executedproposals — show the last executed proposals

⮑ Params: limit (optional, default: 10)

/executedproposals limit=5

/lastproposal — show the most recent proposal

🌐 Gnovalidator bot

⏱️ Available periods

  • current_week
  • current_month
  • current_year
  • all_time

📡 Commands

🚦 Particpate rate command Shows the participation rate of validators for a given period. Examples:

/status [period=...] [limit=N]

  • /status (defaults: period=current_month, limit=10)
  • /status period=current_month limit=5

🕒 Up time command Displays uptime statistics of validator. Examples:

/uptime [limit=N]

  • /uptime (default: limit=10)
  • /uptime limit=3

💪 Tx contribution command Shows each validator’s contribution to transaction inclusion. Examples: /tx_contrib [period=...] [limit=N]

  • /tx_contrib (defaults: period=current_month, limit=10)
  • /tx_contrib period=current_year limit=20

🚧 Subscribe missing block command Displays how many blocks each validator missed for a given period. Examples:

/missing [period=...] [limit=N]

  • /missing (defaults: period=current_month, limit=10)
  • /missing period=all_time limit=50

📬 Subscribe command Show your active subscriptions and available validators

  • /subscribe list

Enable alerts for one or more validators

  • /subscribe on [addr] [more...]

Disable alerts for one or more validators

  • /subscribe off [addr] [more...]\n

Enable alerts for all validators

  • /subscribe on all

Disable alerts for all validators

  • /subscribe off all

About

Gno Monitoring

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages