๐Ÿ›ก๏ธ Pi-hole Exporter

๐ŸŽฏ Purpose

pihole_exporter exposes Pi-hole DNS and ad-blocking metrics for Prometheus and Grafana. In this environment, it provides:


โš™๏ธ How It Works


๐Ÿงฉ Key Concepts

๐Ÿ“Š Summary Metrics

These gauges cover the rolling last 24 hours, the same numbers shown on the Pi-hole web dashboard:

๐Ÿ”Ž Breakdown Metrics

Pi-hole forwards to the local Unbound resolver (127.0.0.1#5335), so that is the main upstream destination. The forward destination metrics also include Pi-holeโ€™s own cache and blocklist entries.

๐Ÿท๏ธ Labels

Every metric carries a hostname label with the address the exporter used to reach Pi-hole. Because each exporter reads its local API, this is 127.0.0.1 on both hosts. Use the Prometheus instance label (dns-0 or dns-1) to tell the servers apart.

The top lists are snapshots. Entries that drop out of a top list stop being exported, so these series come and go over time.


๐Ÿ“ Configuration & Service

Binary: /usr/local/bin/pihole_exporter, a link to the versioned binary in /opt/pihole_exporter

Password file: /etc/pihole_exporter/password (root:pihole-exporter, mode 0640)

Service: pihole_exporter (systemd)

Listener: 0.0.0.0:9617

The service runs as the pihole-exporter system user. All settings are passed as command-line flags in the systemd unit. The password is read from the password file through -pihole_password_file, so it never appears in the unit file or the process list.

Role settings (roles/pihole_exporter_setup/defaults/main/main.yml):

Prometheus settings (roles/prometheus_setup/defaults/main/main.yml):

The password is supplied through Ansible vault; do not put it in this page, metric labels, or other public configuration.


๐Ÿš€ Deployment

The pihole_exporter inventory group in inventory/dns/inventory.ini contains the Pi-hole hosts. Deploy the exporter with:

source /opt/python_3.12/bin/activate
ansible-playbook -i inventory/dns/inventory.ini playbooks/prometheus/deploy_pihole_exporter.yml

The playbook loads roles/pihole/defaults/main/vault.yml so the exporter uses the same vaulted pihole_password as the pihole role. To use a Pi-hole application password instead (Settings โ†’ Web interface / API), set pihole_exporter_setup_password in vault.

Refresh Prometheus scrape targets after inventory changes:

ansible-playbook playbooks/prometheus/deploy_prometheus_exporters.yml

This refresh command uses the repositoryโ€™s full combined inventory (inventory/); do not limit it to inventory/dns/, or exporter groups from other inventories will be omitted from that run.

Deploy the Pi-hole alert rules with the main Prometheus playbook, then refresh the exporter targets again:

ansible-playbook -i inventory/prometheus/inventory.ini playbooks/prometheus/deploy_prometheus.yml
ansible-playbook playbooks/prometheus/deploy_prometheus_exporters.yml

Syntax-check the deployment playbook before applying changes:

ansible-playbook -i inventory/dns/inventory.ini --syntax-check playbooks/prometheus/deploy_pihole_exporter.yml

๐Ÿ”” Alert Rules

The pihole group in prometheus.rules.yml contains:

prometheus.yml does not currently have an alerting: section, so these alerts appear in Prometheus and Grafana but are not sent to Alertmanager.


๐Ÿ” Common Prometheus Queries


๐Ÿ“Š Grafana Usage Notes

No Pi-hole dashboard is provisioned yet. The exporter project publishes one (grafana.com ID 10176) that works with these metrics.

When building panels, group by instance rather than hostname, because hostname is 127.0.0.1 on both servers. Clients usually query both Pi-hole servers, so add the two serversโ€™ counts together for a network-wide total.


๐Ÿ› ๏ธ Troubleshooting

โŒ Exporter Target Is Down

Check:

๐Ÿ“ญ Target Is Up but There Is No Pi-hole Data

Check:

This is the condition that triggers PiholeMetricsAbsent. If only one host is affected, its web password may differ from the other hostโ€™s.

๐Ÿšซ Blocking Disabled or Empty Blocklist

Check:

๐Ÿ› ๏ธ Quick Verification Commands

systemctl status pihole_exporter
journalctl -u pihole_exporter -n 50 --no-pager
curl -s http://localhost:9617/metrics | grep -E '^pihole_(status|domains_being_blocked)'
/usr/local/bin/pihole_exporter -version

๐Ÿ” Security & Operational Guidance


๐Ÿงพ Summary

pihole_exporter exposes Pi-hole query, blocking, client, and upstream metrics from each DNS server for Prometheus to scrape. Its alert rules flag a stopped exporter, disabled blocking, or an empty blocklist, while Node Exporter separately reports host-level health for the same servers.