This commit is contained in:
William Gibson 2023-07-26 03:15:44 -04:00
parent 4dad8e2fe3
commit d148c6d95d
No known key found for this signature in database
8 changed files with 54 additions and 54 deletions

View File

@ -1,6 +1,6 @@
# Contributing # Contributing
PI-Hole exporter is an open source project, completely opened to be a community-driven project. Pi-hole exporter is an open source project, completely opened to be a community-driven project.
If you'd like to contribute, you are free to do so. If you'd like to contribute, you are free to do so.

View File

@ -1,10 +1,10 @@
# PI-Hole Prometheus Exporter # Pi-hole Prometheus Exporter
![Build/Push (master)](https://github.com/eko/pihole-exporter/workflows/Build/Push%20(master)/badge.svg) ![Build/Push (master)](https://github.com/eko/pihole-exporter/workflows/Build/Push%20(master)/badge.svg)
[![GoDoc](https://godoc.org/github.com/eko/pihole-exporter?status.png)](https://godoc.org/github.com/eko/pihole-exporter) [![GoDoc](https://godoc.org/github.com/eko/pihole-exporter?status.png)](https://godoc.org/github.com/eko/pihole-exporter)
[![GoReportCard](https://goreportcard.com/badge/github.com/eko/pihole-exporter)](https://goreportcard.com/report/github.com/eko/pihole-exporter) [![GoReportCard](https://goreportcard.com/badge/github.com/eko/pihole-exporter)](https://goreportcard.com/report/github.com/eko/pihole-exporter)
This is a Prometheus exporter for [PI-Hole](https://pi-hole.net/)'s Raspberry PI ad blocker. This is a Prometheus exporter for [Pi-hole](https://pi-hole.net/)'s Raspberry PI ad blocker.
![Grafana dashboard](https://raw.githubusercontent.com/eko/pihole-exporter/master/dashboard.jpg) ![Grafana dashboard](https://raw.githubusercontent.com/eko/pihole-exporter/master/dashboard.jpg)
@ -143,7 +143,7 @@ $ ./pihole_exporter -pihole_hostname 192.168.1.10 -pihole_api_token $API_TOKEN
```bash ```bash
2019/05/09 20:19:52 ------------------------------------ 2019/05/09 20:19:52 ------------------------------------
2019/05/09 20:19:52 - PI-Hole exporter configuration - 2019/05/09 20:19:52 - Pi-hole exporter configuration -
2019/05/09 20:19:52 ------------------------------------ 2019/05/09 20:19:52 ------------------------------------
2019/05/09 20:19:52 PIHoleHostname : 192.168.1.10 2019/05/09 20:19:52 PIHoleHostname : 192.168.1.10
2019/05/09 20:19:52 PIHolePassword : azerty 2019/05/09 20:19:52 PIHolePassword : azerty
@ -183,16 +183,16 @@ scrape_configs:
## Available CLI options ## Available CLI options
```bash ```bash
# Hostname of the host(s) where PI-Hole is installed # Hostname of the host(s) where Pi-hole is installed
-pihole_hostname string (optional) (default "127.0.0.1") -pihole_hostname string (optional) (default "127.0.0.1")
# Password defined on the PI-Hole interface # Password defined on the Pi-hole interface
-pihole_password string (optional) -pihole_password string (optional)
# Timeout to connect and retrieve data from a Pi-Hole instance # Timeout to connect and retrieve data from a Pi-hole instance
-timeout duration (optional) (default 5s) -timeout duration (optional) (default 5s)
# WEBPASSWORD / api token defined on the PI-Hole interface at `/etc/pihole/setupVars.conf` # WEBPASSWORD / api token defined on the Pi-hole interface at `/etc/pihole/setupVars.conf`
-pihole_api_token string (optional) -pihole_api_token string (optional)
# Address to be used for the exporter # Address to be used for the exporter
@ -217,12 +217,12 @@ scrape_configs:
| pihole_unique_clients | This represent the number of unique clients seen | | pihole_unique_clients | This represent the number of unique clients seen |
| pihole_dns_queries_all_types | This represent the number of DNS queries made for all types | | pihole_dns_queries_all_types | This represent the number of DNS queries made for all types |
| pihole_reply | This represent the number of replies made for all types | | pihole_reply | This represent the number of replies made for all types |
| pihole_top_queries | This represent the number of top queries made by PI-Hole by domain | | pihole_top_queries | This represent the number of top queries made by Pi-hole by domain |
| pihole_top_ads | This represent the number of top ads made by PI-Hole by domain | | pihole_top_ads | This represent the number of top ads made by Pi-hole by domain |
| pihole_top_sources | This represent the number of top sources requests made by PI-Hole by source host | | pihole_top_sources | This represent the number of top sources requests made by Pi-hole by source host |
| pihole_forward_destinations | This represent the number of forward destinations requests made by PI-Hole by destination | | pihole_forward_destinations | This represent the number of forward destinations requests made by Pi-hole by destination |
| pihole_querytypes | This represent the number of queries made by PI-Hole by type | | pihole_querytypes | This represent the number of queries made by Pi-hole by type |
| pihole_status | This represent if PI-Hole is enabled | | pihole_status | This represent if Pi-hole is enabled |
## Pihole-Exporter Helm Chart ## Pihole-Exporter Helm Chart

View File

@ -194,7 +194,7 @@ func (c Config) PIHoleLoginURL() string {
func (c EnvConfig) show() { func (c EnvConfig) show() {
val := reflect.ValueOf(&c).Elem() val := reflect.ValueOf(&c).Elem()
log.Info("------------------------------------") log.Info("------------------------------------")
log.Info("- PI-Hole exporter configuration -") log.Info("- Pi-hole exporter configuration -")
log.Info("------------------------------------") log.Info("------------------------------------")
log.Info("Go version: ", runtime.Version()) log.Info("Go version: ", runtime.Version())
for i := 0; i < val.NumField(); i++ { for i := 0; i < val.NumField(); i++ {
@ -213,6 +213,6 @@ func (c EnvConfig) show() {
func showAuthenticationMethod(name string, length int) { func showAuthenticationMethod(name string, length int) {
if length > 0 { if length > 0 {
log.Info(fmt.Sprintf("Pi-Hole Authentication Method : %s", name)) log.Info(fmt.Sprintf("Pi-hole Authentication Method : %s", name))
} }
} }

View File

@ -76,7 +76,7 @@
} }
] ]
}, },
"description": "This is a PI-Hole dashboard when using the https://github.com/eko/pihole-exporter Prometheus exporter with an Influxdb2 Datasource", "description": "This is a Pi-hole dashboard when using the https://github.com/eko/pihole-exporter Prometheus exporter with an Influxdb2 Datasource",
"editable": true, "editable": true,
"fiscalYearStartMonth": 0, "fiscalYearStartMonth": 0,
"gnetId": 17094, "gnetId": 17094,
@ -1777,7 +1777,7 @@
] ]
}, },
"timezone": "", "timezone": "",
"title": "PI-Hole Exporter Influxdb 2 (Flux)", "title": "Pi-hole Exporter Influxdb 2 (Flux)",
"uid": "KILVhlozd", "uid": "KILVhlozd",
"version": 1, "version": 1,
"weekStart": "" "weekStart": ""

View File

@ -67,7 +67,7 @@
} }
] ]
}, },
"description": "This is a PI-Hole dashboard when using the https://github.com/eko/pihole-exporter Prometheus exporter", "description": "This is a Pi-hole dashboard when using the https://github.com/eko/pihole-exporter Prometheus exporter",
"editable": true, "editable": true,
"gnetId": 10176, "gnetId": 10176,
"graphTooltip": 0, "graphTooltip": 0,
@ -1522,7 +1522,7 @@
] ]
}, },
"timezone": "", "timezone": "",
"title": "PI-Hole Exporter", "title": "Pi-hole Exporter",
"uid": "PI-Hole-Exporter", "uid": "Pi-hole-Exporter",
"version": 31 "version": 31
} }

View File

@ -6,7 +6,7 @@ import (
) )
var ( var (
// DomainsBlocked - The number of domains being blocked by PI-Hole. // DomainsBlocked - The number of domains being blocked by Pi-hole.
DomainsBlocked = prometheus.NewGaugeVec( DomainsBlocked = prometheus.NewGaugeVec(
prometheus.GaugeOpts{ prometheus.GaugeOpts{
Name: "domains_being_blocked", Name: "domains_being_blocked",
@ -16,7 +16,7 @@ var (
[]string{"hostname"}, []string{"hostname"},
) )
// DNSQueriesToday - The number of DNS requests made over PI-Hole over the current day. // DNSQueriesToday - The number of DNS requests made over Pi-hole over the current day.
DNSQueriesToday = prometheus.NewGaugeVec( DNSQueriesToday = prometheus.NewGaugeVec(
prometheus.GaugeOpts{ prometheus.GaugeOpts{
Name: "dns_queries_today", Name: "dns_queries_today",
@ -26,7 +26,7 @@ var (
[]string{"hostname"}, []string{"hostname"},
) )
// AdsBlockedToday - The number of ads blocked by PI-Hole over the current day. // AdsBlockedToday - The number of ads blocked by Pi-hole over the current day.
AdsBlockedToday = prometheus.NewGaugeVec( AdsBlockedToday = prometheus.NewGaugeVec(
prometheus.GaugeOpts{ prometheus.GaugeOpts{
Name: "ads_blocked_today", Name: "ads_blocked_today",
@ -36,7 +36,7 @@ var (
[]string{"hostname"}, []string{"hostname"},
) )
// AdsPercentageToday - The percentage of ads blocked by PI-Hole over the current day. // AdsPercentageToday - The percentage of ads blocked by Pi-hole over the current day.
AdsPercentageToday = prometheus.NewGaugeVec( AdsPercentageToday = prometheus.NewGaugeVec(
prometheus.GaugeOpts{ prometheus.GaugeOpts{
Name: "ads_percentage_today", Name: "ads_percentage_today",
@ -46,7 +46,7 @@ var (
[]string{"hostname"}, []string{"hostname"},
) )
// UniqueDomains - The number of unique domains seen by PI-Hole. // UniqueDomains - The number of unique domains seen by Pi-hole.
UniqueDomains = prometheus.NewGaugeVec( UniqueDomains = prometheus.NewGaugeVec(
prometheus.GaugeOpts{ prometheus.GaugeOpts{
Name: "unique_domains", Name: "unique_domains",
@ -56,7 +56,7 @@ var (
[]string{"hostname"}, []string{"hostname"},
) )
// QueriesForwarded - The number of queries forwarded by PI-Hole. // QueriesForwarded - The number of queries forwarded by Pi-hole.
QueriesForwarded = prometheus.NewGaugeVec( QueriesForwarded = prometheus.NewGaugeVec(
prometheus.GaugeOpts{ prometheus.GaugeOpts{
Name: "queries_forwarded", Name: "queries_forwarded",
@ -66,7 +66,7 @@ var (
[]string{"hostname"}, []string{"hostname"},
) )
// QueriesCached - The number of queries cached by PI-Hole. // QueriesCached - The number of queries cached by Pi-hole.
QueriesCached = prometheus.NewGaugeVec( QueriesCached = prometheus.NewGaugeVec(
prometheus.GaugeOpts{ prometheus.GaugeOpts{
Name: "queries_cached", Name: "queries_cached",
@ -76,7 +76,7 @@ var (
[]string{"hostname"}, []string{"hostname"},
) )
// ClientsEverSeen - The number of clients ever seen by PI-Hole. // ClientsEverSeen - The number of clients ever seen by Pi-hole.
ClientsEverSeen = prometheus.NewGaugeVec( ClientsEverSeen = prometheus.NewGaugeVec(
prometheus.GaugeOpts{ prometheus.GaugeOpts{
Name: "clients_ever_seen", Name: "clients_ever_seen",
@ -86,7 +86,7 @@ var (
[]string{"hostname"}, []string{"hostname"},
) )
// UniqueClients - The number of unique clients seen by PI-Hole. // UniqueClients - The number of unique clients seen by Pi-hole.
UniqueClients = prometheus.NewGaugeVec( UniqueClients = prometheus.NewGaugeVec(
prometheus.GaugeOpts{ prometheus.GaugeOpts{
Name: "unique_clients", Name: "unique_clients",
@ -96,7 +96,7 @@ var (
[]string{"hostname"}, []string{"hostname"},
) )
// DNSQueriesAllTypes - The number of DNS queries made for all types by PI-Hole. // DNSQueriesAllTypes - The number of DNS queries made for all types by Pi-hole.
DNSQueriesAllTypes = prometheus.NewGaugeVec( DNSQueriesAllTypes = prometheus.NewGaugeVec(
prometheus.GaugeOpts{ prometheus.GaugeOpts{
Name: "dns_queries_all_types", Name: "dns_queries_all_types",
@ -106,7 +106,7 @@ var (
[]string{"hostname"}, []string{"hostname"},
) )
// Reply - The number of replies made for every types by PI-Hole. // Reply - The number of replies made for every types by Pi-hole.
Reply = prometheus.NewGaugeVec( Reply = prometheus.NewGaugeVec(
prometheus.GaugeOpts{ prometheus.GaugeOpts{
Name: "reply", Name: "reply",
@ -116,68 +116,68 @@ var (
[]string{"hostname", "type"}, []string{"hostname", "type"},
) )
// TopQueries - The number of top queries made by PI-Hole by domain. // TopQueries - The number of top queries made by Pi-hole by domain.
TopQueries = prometheus.NewGaugeVec( TopQueries = prometheus.NewGaugeVec(
prometheus.GaugeOpts{ prometheus.GaugeOpts{
Name: "top_queries", Name: "top_queries",
Namespace: "pihole", Namespace: "pihole",
Help: "This represent the number of top queries made by PI-Hole by domain", Help: "This represent the number of top queries made by Pi-hole by domain",
}, },
[]string{"hostname", "domain"}, []string{"hostname", "domain"},
) )
// TopAds - The number of top ads made by PI-Hole by domain. // TopAds - The number of top ads made by Pi-hole by domain.
TopAds = prometheus.NewGaugeVec( TopAds = prometheus.NewGaugeVec(
prometheus.GaugeOpts{ prometheus.GaugeOpts{
Name: "top_ads", Name: "top_ads",
Namespace: "pihole", Namespace: "pihole",
Help: "This represent the number of top ads made by PI-Hole by domain", Help: "This represent the number of top ads made by Pi-hole by domain",
}, },
[]string{"hostname", "domain"}, []string{"hostname", "domain"},
) )
// TopSources - The number of top sources requests made by PI-Hole by source host. // TopSources - The number of top sources requests made by Pi-hole by source host.
TopSources = prometheus.NewGaugeVec( TopSources = prometheus.NewGaugeVec(
prometheus.GaugeOpts{ prometheus.GaugeOpts{
Name: "top_sources", Name: "top_sources",
Namespace: "pihole", Namespace: "pihole",
Help: "This represent the number of top sources requests made by PI-Hole by source host", Help: "This represent the number of top sources requests made by Pi-hole by source host",
}, },
[]string{"hostname", "source"}, []string{"hostname", "source"},
) )
// ForwardDestinations - The number of forward destinations requests made by PI-Hole by destination. // ForwardDestinations - The number of forward destinations requests made by Pi-hole by destination.
ForwardDestinations = prometheus.NewGaugeVec( ForwardDestinations = prometheus.NewGaugeVec(
prometheus.GaugeOpts{ prometheus.GaugeOpts{
Name: "forward_destinations", Name: "forward_destinations",
Namespace: "pihole", Namespace: "pihole",
Help: "This represent the number of forward destinations requests made by PI-Hole by destination", Help: "This represent the number of forward destinations requests made by Pi-hole by destination",
}, },
[]string{"hostname", "destination"}, []string{"hostname", "destination"},
) )
// QueryTypes - The number of queries made by PI-Hole by type. // QueryTypes - The number of queries made by Pi-hole by type.
QueryTypes = prometheus.NewGaugeVec( QueryTypes = prometheus.NewGaugeVec(
prometheus.GaugeOpts{ prometheus.GaugeOpts{
Name: "querytypes", Name: "querytypes",
Namespace: "pihole", Namespace: "pihole",
Help: "This represent the number of queries made by PI-Hole by type", Help: "This represent the number of queries made by Pi-hole by type",
}, },
[]string{"hostname", "type"}, []string{"hostname", "type"},
) )
// Status - Is PI-Hole enabled? // Status - Is Pi-hole enabled?
Status = prometheus.NewGaugeVec( Status = prometheus.NewGaugeVec(
prometheus.GaugeOpts{ prometheus.GaugeOpts{
Name: "status", Name: "status",
Namespace: "pihole", Namespace: "pihole",
Help: "This if PI-Hole is enabled", Help: "This if Pi-hole is enabled",
}, },
[]string{"hostname"}, []string{"hostname"},
) )
) )
// Init initializes all Prometheus metrics made available by PI-Hole exporter. // Init initializes all Prometheus metrics made available by Pi-hole exporter.
func Init() { func Init() {
initMetric("domains_blocked", DomainsBlocked) initMetric("domains_blocked", DomainsBlocked)
initMetric("dns_queries_today", DNSQueriesToday) initMetric("dns_queries_today", DNSQueriesToday)

View File

@ -43,7 +43,7 @@ func (c *ClientChannel) String() string {
} }
} }
// Client struct is a PI-Hole client to request an instance of a PI-Hole ad blocker. // Client struct is a Pi-hole client to request an instance of a Pi-hole ad blocker.
type Client struct { type Client struct {
httpClient http.Client httpClient http.Client
interval time.Duration interval time.Duration
@ -51,7 +51,7 @@ type Client struct {
Status chan *ClientChannel Status chan *ClientChannel
} }
// NewClient method initializes a new PI-Hole client. // NewClient method initializes a new Pi-hole client.
func NewClient(config *config.Config, envConfig *config.EnvConfig) *Client { func NewClient(config *config.Config, envConfig *config.EnvConfig) *Client {
err := config.Validate() err := config.Validate()
if err != nil { if err != nil {
@ -135,10 +135,10 @@ func (c *Client) setMetrics(stats *Stats) {
} }
metrics.Status.WithLabelValues(c.config.PIHoleHostname).Set(float64(isEnabled)) metrics.Status.WithLabelValues(c.config.PIHoleHostname).Set(float64(isEnabled))
// Pi-Hole returns a subset of stats when Auth is missing or incorrect. // Pi-hole returns a subset of stats when Auth is missing or incorrect.
// This provides a warning to users that metrics are not complete. // This provides a warning to users that metrics are not complete.
if len(stats.TopQueries) == 0 { if len(stats.TopQueries) == 0 {
log.Warnf("Invalid Authentication - Some metrics may be missing. Please confirm your PI-Hole API token / Password for %s", c.config.PIHoleHostname) log.Warnf("Invalid Authentication - Some metrics may be missing. Please confirm your Pi-hole API token / Password for %s", c.config.PIHoleHostname)
} }
for domain, value := range stats.TopQueries { for domain, value := range stats.TopQueries {
@ -175,7 +175,7 @@ func (c *Client) getPHPSessionID() (sessionID string) {
resp, err := c.httpClient.Do(req) resp, err := c.httpClient.Do(req)
if err != nil { if err != nil {
log.Errorf("An error has occured during login to PI-Hole: %v", err) log.Errorf("An error has occured during login to Pi-hole: %v", err)
} }
for _, cookie := range resp.Cookies() { for _, cookie := range resp.Cookies() {
@ -208,18 +208,18 @@ func (c *Client) getStatistics() (*Stats, error) {
resp, err := c.httpClient.Do(req) resp, err := c.httpClient.Do(req)
if err != nil { if err != nil {
return nil, fmt.Errorf("an error has occured during retrieving PI-Hole statistics: %w", err) return nil, fmt.Errorf("an error has occured during retrieving Pi-hole statistics: %w", err)
} }
defer resp.Body.Close() defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body) body, err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to read PI-Hole statistics HTTP response: %w", err) return nil, fmt.Errorf("unable to read Pi-hole statistics HTTP response: %w", err)
} }
err = json.Unmarshal(body, stats) err = json.Unmarshal(body, stats)
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to unmarshal PI-Hole statistics to statistics struct model: %w", err) return nil, fmt.Errorf("unable to unmarshal Pi-hole statistics to statistics struct model: %w", err)
} }
return stats, nil return stats, nil

View File

@ -6,7 +6,7 @@ const (
enabledStatus = "enabled" enabledStatus = "enabled"
) )
// Stats struct is the PI-Hole statistics JSON API corresponding model. // Stats struct is the Pi-hole statistics JSON API corresponding model.
type Stats struct { type Stats struct {
DomainsBeingBlocked int `json:"domains_being_blocked"` DomainsBeingBlocked int `json:"domains_being_blocked"`
DNSQueriesToday int `json:"dns_queries_today"` DNSQueriesToday int `json:"dns_queries_today"`