diff --git a/internal/adguard/client.go b/internal/adguard/client.go index da61136..ce94d0f 100644 --- a/internal/adguard/client.go +++ b/internal/adguard/client.go @@ -1,123 +1,169 @@ package adguard import ( - "encoding/json" - "fmt" - "io/ioutil" - "log" - "net/http" - "os" - "time" + "encoding/json" + "fmt" + "io/ioutil" + "log" + "net/http" + "os" + "time" - "github.com/ebrianne/adguard-exporter/internal/metrics" + "github.com/ebrianne/adguard-exporter/internal/metrics" ) var ( - statsURLPattern = "%s://%s:%d/control/stats" + statsURLPattern = "%s://%s:%d/control/stats" + logstatsURLPattern = "%s://%s:%d/control/querylog" ) // Client struct is a AdGuard client to request an instance of a AdGuard ad blocker. type Client struct { - httpClient http.Client - interval time.Duration - protocol string - hostname string - port uint16 - b64password string + httpClient http.Client + interval time.Duration + protocol string + hostname string + port uint16 + b64password string } // NewClient method initializes a new AdGuard client. func NewClient(protocol, hostname string, port uint16, b64password string, interval time.Duration) *Client { - if protocol != "http" { - log.Printf("protocol %s is invalid. Must be http.", protocol) - os.Exit(1) - } + if protocol != "http" { + log.Printf("protocol %s is invalid. Must be http.", protocol) + os.Exit(1) + } - return &Client{ - protocol: protocol, - hostname: hostname, - port: port, - b64password: b64password, - interval: interval, - httpClient: http.Client{}, - } + return &Client{ + protocol: protocol, + hostname: hostname, + port: port, + b64password: b64password, + interval: interval, + httpClient: http.Client{}, + } } // Scrape method authenticates and retrieves statistics from AdGuard JSON API // and then pass them as Prometheus metrics. func (c *Client) Scrape() { - for range time.Tick(c.interval) { - stats := c.getStatistics() + for range time.Tick(c.interval) { - c.setMetrics(stats) + //Get the general stats + stats := c.getStatistics() + c.setMetrics(stats) - log.Printf("New tick of statistics: %s", stats.ToString()) - } + //Get the log stats + logstats := c.getLogStatistics() + c.setLogMetrics(logstats) + + log.Printf("New tick of statistics: %s", stats.ToString()) + } } +// Function to set the general stats func (c *Client) setMetrics(stats *Stats) { - metrics.AvgProcessingTime.WithLabelValues(c.hostname).Set(float64(stats.AvgProcessingTime)) - metrics.DnsQueries.WithLabelValues(c.hostname).Set(float64(stats.DnsQueries)) - metrics.BlockedFiltering.WithLabelValues(c.hostname).Set(float64(stats.BlockedFiltering)) - metrics.ParentalFiltering.WithLabelValues(c.hostname).Set(float64(stats.ParentalFiltering)) - metrics.SafeBrowsingFiltering.WithLabelValues(c.hostname).Set(float64(stats.SafeBrowsingFiltering)) - metrics.SafeSearchFiltering.WithLabelValues(c.hostname).Set(float64(stats.SafeSearchFiltering)) + metrics.AvgProcessingTime.WithLabelValues(c.hostname).Set(float64(stats.AvgProcessingTime)) + metrics.DnsQueries.WithLabelValues(c.hostname).Set(float64(stats.DnsQueries)) + metrics.BlockedFiltering.WithLabelValues(c.hostname).Set(float64(stats.BlockedFiltering)) + metrics.ParentalFiltering.WithLabelValues(c.hostname).Set(float64(stats.ParentalFiltering)) + metrics.SafeBrowsingFiltering.WithLabelValues(c.hostname).Set(float64(stats.SafeBrowsingFiltering)) + metrics.SafeSearchFiltering.WithLabelValues(c.hostname).Set(float64(stats.SafeSearchFiltering)) - for l := range stats.TopQueries { - for domain, value := range stats.TopQueries[l] { - metrics.TopQueries.WithLabelValues(c.hostname, domain).Set(float64(value)) - } - } + for l := range stats.TopQueries { + for domain, value := range stats.TopQueries[l] { + metrics.TopQueries.WithLabelValues(c.hostname, domain).Set(float64(value)) + } + } - for l := range stats.TopBlocked { - for domain, value := range stats.TopBlocked[l] { - metrics.TopBlocked.WithLabelValues(c.hostname, domain).Set(float64(value)) - } - } + for l := range stats.TopBlocked { + for domain, value := range stats.TopBlocked[l] { + metrics.TopBlocked.WithLabelValues(c.hostname, domain).Set(float64(value)) + } + } - for l := range stats.TopClients { - for source, value := range stats.TopClients[l] { - metrics.TopClients.WithLabelValues(c.hostname, source).Set(float64(value)) - } - } + for l := range stats.TopClients { + for source, value := range stats.TopClients[l] { + metrics.TopClients.WithLabelValues(c.hostname, source).Set(float64(value)) + } + } } +// Function to get the general stats func (c *Client) getStatistics() *Stats { - var stats Stats + var stats Stats - statsURL := fmt.Sprintf(statsURLPattern, c.protocol, c.hostname, c.port) + statsURL := fmt.Sprintf(statsURLPattern, c.protocol, c.hostname, c.port) - req, err := http.NewRequest("GET", statsURL, nil) - if err != nil { - log.Fatal("An error has occurred when creating HTTP statistics request ", err) - } + req, err := http.NewRequest("GET", statsURL, nil) + if err != nil { + log.Fatal("An error has occurred when creating HTTP statistics request ", err) + } - if c.isUsingPassword() { - c.authenticateRequest(req) - } + if c.isUsingPassword() { + c.authenticateRequest(req) + } - resp, err := c.httpClient.Do(req) - if err != nil { - log.Printf("An error has occurred during login to Adguard: %v", err) - } + resp, err := c.httpClient.Do(req) + if err != nil { + log.Printf("An error has occurred during login to Adguard: %v", err) + } - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - log.Println("Unable to read Adguard statistics HTTP response", err) - } + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + log.Println("Unable to read Adguard statistics HTTP response", err) + } - err = json.Unmarshal(body, &stats) - if err != nil { - log.Println("Unable to unmarshal Adguard statistics to statistics struct model", err) - } + err = json.Unmarshal(body, &stats) + if err != nil { + log.Println("Unable to unmarshal Adguard statistics to statistics struct model", err) + } - return &stats + return &stats } func (c *Client) isUsingPassword() bool { - return len(c.b64password) > 0 + return len(c.b64password) > 0 } func (c *Client) authenticateRequest(req *http.Request) { - req.Header.Add("Authorization", "Basic "+c.b64password) + req.Header.Add("Authorization", "Basic "+c.b64password) +} + +// Function to get the log metrics +func (c *Client) setLogMetrics(logstats *LogStats) { + +} + +// Function to get the log stats +func (c *Client) getLogStatistics() *LogStats { + var logstats LogStats + + logstatsURL := fmt.Sprintf(logstatsURLPattern, c.protocol, c.hostname, c.port) + + req, err := http.NewRequest("GET", statsURL, nil) + if err != nil { + log.Fatal("An error has occurred when creating HTTP statistics request ", err) + } + + if c.isUsingPassword() { + c.authenticateRequest(req) + } + + resp, err := c.httpClient.Do(req) + if err != nil { + log.Printf("An error has occurred during login to Adguard: %v", err) + } + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + log.Println("Unable to read Adguard statistics HTTP response", err) + } + + // err = json.Unmarshal(body, &logstats) + // if err != nil { + // log.Println("Unable to unmarshal Adguard log statistics to log statistics struct model", err) + // } + + return &logstats } diff --git a/internal/adguard/model.go b/internal/adguard/model.go index a60ed99..bf8eb6b 100644 --- a/internal/adguard/model.go +++ b/internal/adguard/model.go @@ -15,6 +15,11 @@ type Stats struct { TopClients []map[string]int `json:"top_clients"` } +// LogStats struct for the Adguard log statistics JSON API corresponding model. +type LogStats struct { + +} + // ToString method returns a string of the current statistics struct. func (s *Stats) ToString() string { return fmt.Sprintf("%d ads blocked / %d total DNS queries", s.BlockedFiltering, s.DnsQueries)