This repository contains Grafana dashboards and monitoring infrastructure for the Zeam blockchain node.
This repository provides:
- Grafana Dashboards: Pre-configured dashboards for monitoring Zeam node performance
- Docker Compose Setup: Complete monitoring stack with Prometheus and Grafana
- Prometheus Configuration: Templates and examples for Prometheus setup
- Docker and Docker Compose installed
- A running Zeam node with metrics enabled
A basic Prometheus configuration is included in prometheus/prometheus.yml that will work out of the box.
Option A: Use the included configuration (Recommended for quick start)
The repository includes a basic prometheus/prometheus.yml that will start monitoring:
- Prometheus itself (localhost:9090)
- A Zeam node running on the host (host.docker.internal:8081 using lean-quickstart)
- Node exporter (host.docker.internal:9100, will show as "down" if not running)
Option B: Generate custom configuration (Advanced users) If you have access to the main Zeam repository, you can generate a custom configuration:
# From your Zeam repository
./zig-out/bin/zeam generate_prometheus_config --output /path/to/zeam-dashboards/prometheus/prometheus.yml# Clone this repository
git clone https://github.com/blockblaz/zeam-dashboards.git
cd zeam-dashboards
# Start Prometheus and Grafana (uses included configuration)
docker-compose up -d- Grafana: http://localhost:3001 (admin/admin)
- Prometheus: http://localhost:9090
Data sources (Prometheus and Infinity) are automatically provisioned β no manual configuration needed.
The main dashboard (grafana/dashboards/zeam_main.json) monitors:
- P95 Block Processing Time: 95th percentile of block processing duration (
chain_onblock_duration_seconds)
The fork choice tree dashboard (grafana/dashboards/zeam_forkchoice.json) provides real-time visualization of the consensus fork choice:
- Interactive Node Graph: Visual representation of the fork choice tree showing blocks and their relationships
- Color-Coded Arc Borders:
- π£ Purple: Finalized blocks (immutable canonical chain)
- π΅ Blue: Justified blocks (2/3 supermajority checkpoint)
- π Orange: Current chain head
- π’ Green: Timely blocks (normal blocks)
- β« Gray: Orphaned blocks (historical forks that diverged before finalization)
- Arc Border Completeness: Represents validator weight (larger border = more validator support)
- Best Child Path: Edges showing parent-child relationships in the fork tree
- Chain Progress: Time series showing head, justified, and finalized slot progression
- Slots Parameter: Shows last 50 slots by default (editable in the panel query URL
?slots=N)
The state transition dashboard (grafana/dashboards/zeam_state_transition.json) monitors state transition performance and justifications cache:
- Get Justification Time (P50/P95): Latency percentiles for the justification retrieval path
- State Transition Time by Phase: Stacked breakdown of slots, blocks, attestations, justifications processing
- SSZ Hashing Performance: Merkleization timings for state root, validation, and block header hash
- Get Justification Time (Avg): Gauge with green/yellow/red thresholds
- Chain Progress: Current head, justified, and finalized slot numbers
- Processing Throughput: Slots and attestations processed per second
- Overall State Transition Time: End-to-end P50/P95/P99 latency
- Justifications Cache Hit/Miss Rate: Cache throughput
- Justifications Cache Hit/Miss Time: Average latency for cache hits vs misses
- Justifications Cache Miss/Hit Time Ratio: Performance penalty for cache misses
- Justifications Cache Hit Ratio: Hit percentage with red/yellow/green thresholds
- Justifications Cache Hits/Misses (Total): Cumulative counters since process start
API Endpoint: The fork choice dashboard fetches data from /api/forkchoice/graph endpoint on your Zeam node
If you have your own Grafana setup and want to import the fork choice dashboard without using the Docker Compose stack:
Prerequisites:
-
Install the yesoreyeram-infinity-datasource plugin:
- Official install docs (see for version-specific steps):
https://grafana.com/docs/plugins/yesoreyeram-infinity-datasource/latest/setup/installation/
- Via Grafana UI:
- Open the menu (Grafana icon)
- Administration β Plugins and data β Plugins
- Search for "Infinity" (by Grafana Labs)
- Click Infinity β Install
- Via CLI:
grafana-cli plugins install yesoreyeram-infinity-datasource
- Official install docs (see for version-specific steps):
-
Configure the Infinity data source:
- Go to Configuration β Data Sources β Add data source
- Search for "Infinity" and select it
- Set a name (e.g., "infinity") and save
- Note: No need to add a Base URL or params here; set the URL/params in the panel query.
Import the Dashboard:
- Download
grafana/dashboards/zeam_forkchoice.jsonfrom this repository - In Grafana: Dashboard β Import Dashboard β Upload JSON file
- Select your Infinity data source when prompted
- After import, edit the dashboard panel queries to update the API endpoint URL and split nodes/edges:
- Edit panel β Query tab
- Ensure you have two queries (nodes and edges). If you only see one, duplicate it.
- Query A (nodes):
- URL:
http://YOUR_ZEAM_NODE:8081/api/forkchoice/graph?slots=50 - Rows/Root (Parsing options & Result fields):
nodes - Format: Nodes β Node Graph
- URL:
- Query B (edges):
- URL:
http://YOUR_ZEAM_NODE:8081/api/forkchoice/graph?slots=50 - Rows/Root (Parsing options & Result fields):
edges - Format: Edges β Node Graph
- URL:
- Adjust
slotsparameter as needed (max: 200)
Data Source Configuration Details:
- Type: JSON
- Source: URL
- Format: Table
- URL:
http://YOUR_ZEAM_NODE:8081/api/forkchoice/graph?slots=50 - Method: GET
- Rows/Root (Parsing options & Result fields):
- For nodes query:
nodes - For edges query:
edges - Do not leave Rows/Root empty; otherwise Grafana will treat
nodesandedgesas string fields in one frame and the Node Graph panel won't render.
- For nodes query:
Docker on macOS note:
- If Grafana runs in Docker and your Zeam node runs on the host, use
http://host.docker.internal:8081/...in the query URL instead ofhttp://localhost:8081/....
Visualization note:
- The panel visualization must be set to Node Graph.
Node Circle Numbers Explained:
- First number (mainStat): Validator weight/votes supporting that block
- Second number (secondaryStat): Slot number
The repository includes a basic prometheus/prometheus.yml configuration that works out of the box. You can customize it for your specific setup:
Basic Configuration Includes:
- Prometheus self-monitoring (localhost:9090)
- Zeam node monitoring (host.docker.internal:8081)
- Node exporter (host.docker.internal:9100)
Customizing the Configuration:
- Edit
prometheus/prometheus.ymlto add your specific targets - Update scrape intervals as needed
- Add alert rules and retention policies
For Advanced Users: If you have access to the main Zeam repository, you can generate a custom configuration using the Zeam CLI:
./zig-out/bin/zeam generate_prometheus_config --output prometheus/prometheus.yml- Node.js (for dashboard scripts)
npm installTo edit or extend an existing Grafana dashboard with minimal diff:
- Grab the
.jsondashboard file from the current branch - Import the file to Grafana via the web UI at
/dashboard/import(keep the same UID) - Visually edit the dashboard in the Grafana UI
- Once done, make sure to leave the exact same visual aspect as before: same refresh interval, time range, etc.
- Save the dashboard (CTRL+S)
- Run
npm run download(see below) - Check
git diffof updated dashboards, commit, push and open your PR
-
Generate a Grafana API token:
- Open Grafana β Administration β Service accounts
- Create a new service account with Editor role
- Generate a token and copy it
-
Create a file
.secrets.envin the project root:
GRAFANA_API_KEY=your_token_here
GRAFANA_URL=http://localhost:3001- Run the download script:
npm run downloadThe script will:
- Fetch all dashboards with
zeam_UID prefix from the Grafana API - Only update dashboards that already exist locally (ignores test duplicates)
- Run each dashboard through the lint/normalize pipeline
- Write deterministic JSON output (
JSON.stringifywith 2-space indent) - Preserve the version number to minimize diff noise
Lint all dashboards in place (normalizes formatting, datasource UIDs, tags, timezone, etc.):
npm run lint-dashboardsChecks that all dashboards are properly linted β fails if any changes are needed:
npm run validate-dashboards- Create the dashboard in the Grafana UI
- Before saving, set the dashboard UID to start with
zeam_(e.g.,zeam_networking):- Dashboard Settings (gear icon) β JSON Model β change the
uidfield
- Dashboard Settings (gear icon) β JSON Model β change the
- Save the dashboard in Grafana (CTRL+S)
- Create a local placeholder file so the download script picks it up:
echo '{}' > grafana/dashboards/zeam_networking.json
- Run the download script to fetch and lint:
npm run download
- Verify with
git diff, commit and open a PR
All dashboard UIDs must start with zeam_ and files must be named {uid}.json:
| Dashboard | UID | File |
|---|---|---|
| Main | zeam_main |
grafana/dashboards/zeam_main.json |
| Fork Choice | zeam_forkchoice |
grafana/dashboards/zeam_forkchoice.json |
| State Transition | zeam_state_transition |
grafana/dashboards/zeam_state_transition.json |
-
Prometheus can't scrape Zeam node:
- Verify Zeam node is running with
--metricsPortflag - Check firewall settings
- Ensure Prometheus config targets match Zeam metrics port
- If your Zeam node is not on the default port 8081, edit
prometheus/prometheus.ymland update the target
- Verify Zeam node is running with
-
Grafana can't connect to Prometheus:
- Verify Prometheus is running:
docker-compose ps - Check data source URL in Grafana
- Ensure both services are on the same Docker network
- Verify Prometheus is running:
-
No metrics appearing:
- Verify Zeam node is generating metrics
- Check Prometheus targets page
- Review Prometheus logs:
docker-compose logs prometheus
View logs for troubleshooting:
# All services
docker-compose logs
# Specific service
docker-compose logs prometheus
docker-compose logs grafana- Fork the repository
- Create a feature branch
- Make your changes
- Test with a local Zeam node
- Submit a pull request
MIT License - see LICENSE file for details.