Grafana’s dashboard builder lets you turn raw Prometheus metrics into intuitive visualizations — stat panels for at-a-glance health, time series for trends, and bar gauges for comparisons. With Prometheus and Node Exporter already collecting Linux host metrics, you have everything needed to build a production-grade server dashboard. This tutorial walks through creating panels for CPU, RAM, load average, disk I/O, and network throughput, using template variables so a single dashboard covers your entire fleet.
Prerequisites
- Prometheus running and scraping Node Exporter on all target hosts (see earlier tutorial in this series)
- Grafana installed and connected to your Prometheus datasource
- Basic familiarity with the Grafana UI (dashboards, panels, PromQL queries)
Step 1 — Verify Node Exporter Is Running and Being Scraped
Before building the dashboard, confirm metrics are arriving in Prometheus.
# On each monitored host, confirm node_exporter is running
sudo systemctl status node_exporter
# In Prometheus (http://:9090), run these instant queries to confirm data:
node_uname_info # should return 1 per host
node_cpu_seconds_total{mode="idle"} # CPU time buckets
node_memory_MemAvailable_bytes # available RAM
node_load1 # 1-minute load average
If any query returns no data, check that Node Exporter is listening on port 9100 and that the target appears as “UP” in Prometheus at Status → Targets.
Step 2 — Create a Dashboard and Add a Template Variable
Template variables let one dashboard serve every host. In Grafana:
- Click Dashboards → New Dashboard → Add a new panel (or use the settings gear icon to go to Variables first).
- Navigate to Dashboard Settings → Variables → Add variable.
- Set Name to
host, Type to Query, and enter the query below.
# Variable query — returns all scraped hostnames
label_values(node_uname_info, nodename)
# In panel PromQL, reference the variable as $host:
node_load1{nodename=~"$host"}
Save the variable and a dropdown labelled host will appear at the top of the dashboard, filtering every panel to the selected server.
Step 3 — Add Stat Panels for CPU and RAM
Stat panels show a single number with colour-coded thresholds — perfect for instant health assessment.
# CPU Usage % (instant)
100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle",nodename=~"$host"}[5m])) * 100)
# RAM Usage % (instant)
100 * (1 - (node_memory_MemAvailable_bytes{nodename=~"$host"} / node_memory_MemTotal_bytes{nodename=~"$host"}))
In the panel editor, set the Unit to Percent (0–100) and add thresholds: green below 70, orange 70–90, red above 90. Under Standard options → Min set 0, Max set 100.
Step 4 — Add a Time Series Panel for Load Average
Time series panels show trends over your selected time range (e.g., last 6 hours). Add a new panel and use three queries to overlay 1, 5, and 15-minute load averages.
# Query A — label: Load 1m
node_load1{nodename=~"$host"}
# Query B — label: Load 5m
node_load5{nodename=~"$host"}
# Query C — label: Load 15m
node_load15{nodename=~"$host"}
Set the unit to Short (dimensionless). Add a reference line at the number of CPU cores (count(node_cpu_seconds_total{mode="idle",nodename=~"$host"})) to visualise saturation.
Step 5 — Add Disk I/O and Network Throughput Panels
# Disk Read throughput (bytes/s)
rate(node_disk_read_bytes_total{nodename=~"$host",device!~"loop.*"}[5m])
# Disk Write throughput (bytes/s)
rate(node_disk_written_bytes_total{nodename=~"$host",device!~"loop.*"}[5m])
# Network receive (bytes/s)
rate(node_network_receive_bytes_total{nodename=~"$host",device!~"lo"}[5m])
# Network transmit (bytes/s)
rate(node_network_transmit_bytes_total{nodename=~"$host",device!~"lo"}[5m])
Set the unit to bytes/sec (SI). Use the Transform → Negative Y option on the transmit query to create a traditional “butterfly” network graph with receive above the zero line and transmit below.
Step 6 — Import a Community Dashboard and Export as JSON
Grafana’s community library includes polished dashboards you can import instantly. Dashboard ID 1860 (“Node Exporter Full”) is the most comprehensive and widely used.
# Import via the Grafana UI:
# Dashboards → Import → enter ID 1860 → Load → select your Prometheus datasource → Import
# Export any dashboard as JSON for version control:
# Dashboard Settings (gear icon) → JSON Model → copy the JSON
# Or via the Grafana API:
curl -s http://admin:password@localhost:3000/api/dashboards/db
-H "Content-Type: application/json"
--data-binary @dashboard-export.json
Store exported JSON files in a Git repository alongside your Prometheus configuration. Tools such as grafana-backup-tool or Grafana’s built-in provisioning system can restore dashboards automatically after a reinstall.
Conclusion
You now have a custom Grafana dashboard displaying CPU usage, RAM availability, load average, disk I/O, and network throughput for every host in your fleet, filtered dynamically by the $host template variable. The imported Node Exporter Full dashboard (ID 1860) provides additional depth, and exporting your dashboards as JSON keeps your monitoring setup reproducible and version-controlled.
Next steps: How to Install and Configure cAdvisor for Container Monitoring on RHEL 9, How to Use Prometheus Blackbox Exporter for Endpoint Monitoring on RHEL 9, and How to Configure SNMP Monitoring on RHEL 9.