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.

#! /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

Grafana

24 Hour

Grafana

7 days

Grafana

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

Grafana

Using FreeIPA to authenticate OpenVPN users on pfSense

I have been fiddling with multiple different authentication methods to centralise the authentication across all my devices and services. ...… Continue reading

Zen Internet, IPv6 and pfsense

Published on February 19, 2017

Basic Telegraf, InfluxDB and Grafana setup

Published on January 26, 2017