Home Graphing Pi-Hole stats with Graphite and Grafana
Post
Cancel

Graphing Pi-Hole stats with Graphite and Grafana

Everyone loves the Pi-Hole. It does a great job blockig ad’s across your entire network. The admin page is also really useful to see whats been going on. Unfortunately the admin interface only gives details of the last 24 hours. I love graphs and graphing things. So i wanted more data.

I already had Graphite and Grafana setup for my previous projects. I just needed a way to get the data into them.

Luckily, the Pi-hole guys provide a nice little API wich provides these details. The following is a small python script is knocked up which pulls and parses that API then forwards the data into my Graphite server.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#! /usr/bin/python

import requests
import socket
import time
import platform

HOSTNAME = "pi-hole"
CARBON_SERVER = "192.168.0.175"
CARBON_PORT = 2003
DELAY = 10 # seconds

def send_msg(message):
#    print ('sending message:\n%s' % message)
    sock = socket.socket()
    sock.connect((CARBON_SERVER, CARBON_PORT))
    sock.sendall(message)
    sock.close()

if __name__ == '__main__':
        while True:
          api = requests.get('http://192.168.0.131/admin/api.php')
          API_out = api.json()
# I could just iterate through the response. But by explicitly defining each one i wont have an issue should the order change.
          domains_blocked = (API_out['domains_being_blocked']).replace(',', '')
          dns_queries_today = (API_out['dns_queries_today']).replace(',', '')
          ads_percentage_today = (API_out['ads_percentage_today'])
          ads_blocked_today = (API_out['ads_blocked_today']).replace(',', '')

          timestamp = int(time.time())

          lines = [
                'pihole.%s.domains_blocked %s %d' % (HOSTNAME, domains_blocked, timestamp),
                'pihole.%s.dns_queries_today %s %d' % (HOSTNAME, dns_queries_today, timestamp),
                'pihole.%s.ads_percentage_today %s %d' % (HOSTNAME, ads_percentage_today, timestamp),
                'pihole.%s.ads_blocked_today %s %d' % (HOSTNAME, ads_blocked_today, timestamp)
          ]
          message = '\n'.join(lines) + '\n'
          send_msg(message)
          time.sleep(DELAY)

My python is probably not the greatest. But it does work. Here are my current graphs.

6 Hour

6 hour graphs

24 Hour

24 hour graphs

7 days

7 day graphs

Finally, to get the “Currently blocked” i use the “Derivative” modifier in Grafana, like this: currently blocking

This post is licensed under CC BY 4.0 by the author.