Starting skeleton for getting log stats

This commit is contained in:
Eldwan Brianne 2020-11-03 16:22:25 +01:00
parent 66fe812e97
commit e770c7fc00
2 changed files with 128 additions and 77 deletions

View File

@ -1,123 +1,169 @@
package adguard package adguard
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log" "log"
"net/http" "net/http"
"os" "os"
"time" "time"
"github.com/ebrianne/adguard-exporter/internal/metrics" "github.com/ebrianne/adguard-exporter/internal/metrics"
) )
var ( 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. // Client struct is a AdGuard client to request an instance of a AdGuard ad blocker.
type Client struct { type Client struct {
httpClient http.Client httpClient http.Client
interval time.Duration interval time.Duration
protocol string protocol string
hostname string hostname string
port uint16 port uint16
b64password string b64password string
} }
// NewClient method initializes a new AdGuard client. // NewClient method initializes a new AdGuard client.
func NewClient(protocol, hostname string, port uint16, b64password string, interval time.Duration) *Client { func NewClient(protocol, hostname string, port uint16, b64password string, interval time.Duration) *Client {
if protocol != "http" { if protocol != "http" {
log.Printf("protocol %s is invalid. Must be http.", protocol) log.Printf("protocol %s is invalid. Must be http.", protocol)
os.Exit(1) os.Exit(1)
} }
return &Client{ return &Client{
protocol: protocol, protocol: protocol,
hostname: hostname, hostname: hostname,
port: port, port: port,
b64password: b64password, b64password: b64password,
interval: interval, interval: interval,
httpClient: http.Client{}, httpClient: http.Client{},
} }
} }
// Scrape method authenticates and retrieves statistics from AdGuard JSON API // Scrape method authenticates and retrieves statistics from AdGuard JSON API
// and then pass them as Prometheus metrics. // and then pass them as Prometheus metrics.
func (c *Client) Scrape() { func (c *Client) Scrape() {
for range time.Tick(c.interval) { for range time.Tick(c.interval) {
stats := c.getStatistics()
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) { func (c *Client) setMetrics(stats *Stats) {
metrics.AvgProcessingTime.WithLabelValues(c.hostname).Set(float64(stats.AvgProcessingTime)) metrics.AvgProcessingTime.WithLabelValues(c.hostname).Set(float64(stats.AvgProcessingTime))
metrics.DnsQueries.WithLabelValues(c.hostname).Set(float64(stats.DnsQueries)) metrics.DnsQueries.WithLabelValues(c.hostname).Set(float64(stats.DnsQueries))
metrics.BlockedFiltering.WithLabelValues(c.hostname).Set(float64(stats.BlockedFiltering)) metrics.BlockedFiltering.WithLabelValues(c.hostname).Set(float64(stats.BlockedFiltering))
metrics.ParentalFiltering.WithLabelValues(c.hostname).Set(float64(stats.ParentalFiltering)) metrics.ParentalFiltering.WithLabelValues(c.hostname).Set(float64(stats.ParentalFiltering))
metrics.SafeBrowsingFiltering.WithLabelValues(c.hostname).Set(float64(stats.SafeBrowsingFiltering)) metrics.SafeBrowsingFiltering.WithLabelValues(c.hostname).Set(float64(stats.SafeBrowsingFiltering))
metrics.SafeSearchFiltering.WithLabelValues(c.hostname).Set(float64(stats.SafeSearchFiltering)) metrics.SafeSearchFiltering.WithLabelValues(c.hostname).Set(float64(stats.SafeSearchFiltering))
for l := range stats.TopQueries { for l := range stats.TopQueries {
for domain, value := range stats.TopQueries[l] { for domain, value := range stats.TopQueries[l] {
metrics.TopQueries.WithLabelValues(c.hostname, domain).Set(float64(value)) metrics.TopQueries.WithLabelValues(c.hostname, domain).Set(float64(value))
} }
} }
for l := range stats.TopBlocked { for l := range stats.TopBlocked {
for domain, value := range stats.TopBlocked[l] { for domain, value := range stats.TopBlocked[l] {
metrics.TopBlocked.WithLabelValues(c.hostname, domain).Set(float64(value)) metrics.TopBlocked.WithLabelValues(c.hostname, domain).Set(float64(value))
} }
} }
for l := range stats.TopClients { for l := range stats.TopClients {
for source, value := range stats.TopClients[l] { for source, value := range stats.TopClients[l] {
metrics.TopClients.WithLabelValues(c.hostname, source).Set(float64(value)) metrics.TopClients.WithLabelValues(c.hostname, source).Set(float64(value))
} }
} }
} }
// Function to get the general stats
func (c *Client) getStatistics() *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) req, err := http.NewRequest("GET", statsURL, nil)
if err != nil { if err != nil {
log.Fatal("An error has occurred when creating HTTP statistics request ", err) log.Fatal("An error has occurred when creating HTTP statistics request ", err)
} }
if c.isUsingPassword() { if c.isUsingPassword() {
c.authenticateRequest(req) c.authenticateRequest(req)
} }
resp, err := c.httpClient.Do(req) resp, err := c.httpClient.Do(req)
if err != nil { if err != nil {
log.Printf("An error has occurred during login to Adguard: %v", err) log.Printf("An error has occurred during login to Adguard: %v", err)
} }
body, err := ioutil.ReadAll(resp.Body) body, err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
log.Println("Unable to read Adguard statistics HTTP response", err) log.Println("Unable to read Adguard statistics HTTP response", err)
} }
err = json.Unmarshal(body, &stats) err = json.Unmarshal(body, &stats)
if err != nil { if err != nil {
log.Println("Unable to unmarshal Adguard statistics to statistics struct model", err) log.Println("Unable to unmarshal Adguard statistics to statistics struct model", err)
} }
return &stats return &stats
} }
func (c *Client) isUsingPassword() bool { func (c *Client) isUsingPassword() bool {
return len(c.b64password) > 0 return len(c.b64password) > 0
} }
func (c *Client) authenticateRequest(req *http.Request) { 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
} }

View File

@ -15,6 +15,11 @@ type Stats struct {
TopClients []map[string]int `json:"top_clients"` 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. // ToString method returns a string of the current statistics struct.
func (s *Stats) ToString() string { func (s *Stats) ToString() string {
return fmt.Sprintf("%d ads blocked / %d total DNS queries", s.BlockedFiltering, s.DnsQueries) return fmt.Sprintf("%d ads blocked / %d total DNS queries", s.BlockedFiltering, s.DnsQueries)