This repository provides lightweight tools to monitor the Gno.land blockchain and its validators.
🧩 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.
- 🛠️ Setup
- 🧪 Local devnet (end-to-end testing)
- 🌍 Multi-Chain Support
- Overview
- Configuration
- API Endpoints with Chain Parameter
- Webhook Management with Chain Scoping
- Telegram Bot Multi-Chain Support
- Prometheus Metrics with Chain Labels
- Known Limitations
- 🔗 Webhook Management (Discord / Slack)
- 📢 ALERTING
- 📝 Expose Metrics from API REST
- 👤 User Management (protected)
- 🔔 Alert Contacts (protected)
- 🕘 Daily Report Schedule (protected)
- 📈 Prometheus Metrics
- ✉️ Telegram Bot
1.Copy the configuration template and edit it:
cd backend
cp config.yaml.template config.yaml
nano config.yaml2.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 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 targetsScenarios 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.
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.
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
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 falseKey points:
- Each chain gets a unique identifier (e.g.,
test12,gnoland1) - Set
enabled: trueto monitor a chain - Set
enabled: falseto disable a chain without removing it default_chainis used when clients don't specify a chain parameter- All disabled chains are ignored during startup
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'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)
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.
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-
GovDAO Bot Single-Chain: The GovDAO bot monitors proposals only on the
default_chain. To monitor proposals on multiple chains, deploy separate instances. -
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.
-
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.
✚ 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"
}Sends alerts (Discord/Slack) when:
- Rpc is down
- The blockchain is stuck on the same block for more than 2 minutes.
- A new validator joins the network.
- A validator's missed block :
- WARNING if a validator missed 5 blocks.
- CRITICAL if a validator missed more of 30 blocks
- Send Resolve Alert.
- Send Daily Report:
The disponible period for metrics:
- current_week
- current_month
- current_year
- all_time
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}]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}...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},...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"},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 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}....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"}]Returns the last block height stored in the database.
curl -X GET ‘localhost:8989/block_height’Response:
{"last_stored": 123456}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"}Returns the moniker for a given validator address.
curl -X GET ‘localhost:8989/addr_moniker?addr=g1ek7ftha29qv4ahtv7jzpc0d57lqy7ynzklht7t’Response:
{"addr":"g1ek7ftha29qv4ahtv7jzpc0d57lqy7ynzklht7t","moniker":"gnocore-val-01"}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 inconfig.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,nullif 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;nullwhen 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 minutescritical_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_week—incident_countnormalized 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 sameincident_countis penalized less when it's spread overcurrent_month/current_yearthan when it's concentrated inlast_24h.downtime_blocks— blocks lost to CRITICAL outagesmissed_blocks— blocks not signed this period (display-only, already reflected insign_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):
- Availability base —
100 × signed_blocks / total_blocksfor the period. - 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.
- Presence — a weighted blend of the two above (default weights: 0.8 signing / 0.2 proposing).
- Incident penalties — points deducted per CRITICAL alert, per WARNING alert, per incident/week-equivalent rate (see
incident_rate_per_weekabove), 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). - 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_24his 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_yearare calendar windows (Monday–Monday, 1st–1st, Jan 1–Jan 1), not rolling ones.sign_rateis 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_countitself never decreases within the period, butincident_rate_per_weekdoes, since its denominator (elapsed days) keeps growing even with no new incidents.critical_count/warning_countpenalties don't benefit from this dilution — they're flat counts, only reset at the next calendar boundary.current_yearis 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. Uselast_24h/current_weekto judge recent behavior andcurrent_yearfor long-term track record — they're deliberately different signals, not the same number at different resolutions.
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>’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>’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"}’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 blocksgnoland_validator_operation_time— Days since validator's last downtime eventgnoland_validator_tx_contribution— Transaction contribution (%) in current monthgnoland_validator_missing_blocks_month— Blocks missed in current monthgnoland_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 chaingnoland_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.
/status — list recent GovDAO proposals
⮑ Params: limit (optional, default: 10)
/status limit=5⮑ Params: limit (optional, default: 10)
/executedproposals limit=5
⏱️ Available periods
current_weekcurrent_monthcurrent_yearall_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




