added support to resolve rdns from adguard (#14)

This commit is contained in:
Rahul Somasundaram 2021-09-09 10:55:02 +05:30 committed by GitHub
parent 07f558a92c
commit e75108942e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 72 additions and 20 deletions

View File

@ -24,6 +24,7 @@ type Config struct {
ServerPort string `config:"server_port"` ServerPort string `config:"server_port"`
Interval time.Duration `config:"interval"` Interval time.Duration `config:"interval"`
LogLimit string `config:"log_limit"` LogLimit string `config:"log_limit"`
RDnsEnabled bool `config:"rdns_enabled"`
} }
func getDefaultConfig() *Config { func getDefaultConfig() *Config {
@ -36,6 +37,7 @@ func getDefaultConfig() *Config {
ServerPort: "9617", ServerPort: "9617",
Interval: 10 * time.Second, Interval: 10 * time.Second,
LogLimit: "1000", LogLimit: "1000",
RDnsEnabled: true,
} }
} }

View File

@ -6,8 +6,10 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log" "log"
"net"
"net/http" "net/http"
"strconv" "strconv"
"strings"
"time" "time"
"github.com/ebrianne/adguard-exporter/internal/metrics" "github.com/ebrianne/adguard-exporter/internal/metrics"
@ -19,6 +21,7 @@ var (
statusURLPattern = "%s://%s:%d/control/status" statusURLPattern = "%s://%s:%d/control/status"
statsURLPattern = "%s://%s:%d/control/stats" statsURLPattern = "%s://%s:%d/control/stats"
logstatsURLPattern = "%s://%s:%d/control/querylog?limit=%s&response_status=\"all\"" logstatsURLPattern = "%s://%s:%d/control/querylog?limit=%s&response_status=\"all\""
resolveRDNSURLPattern = "%s://%s:%d/control/clients/find?%s"
m map[string]int m map[string]int
) )
@ -32,10 +35,11 @@ type Client struct {
port uint16 port uint16
username string username string
password string password string
rdnsenabled bool
} }
// NewClient method initializes a new AdGuard client. // NewClient method initializes a new AdGuard client.
func NewClient(protocol, hostname, username, password, adport string, interval time.Duration, logLimit string) *Client { func NewClient(protocol, hostname, username, password, adport string, interval time.Duration, logLimit string, rdnsenabled bool) *Client {
temp, err := strconv.Atoi(adport) temp, err := strconv.Atoi(adport)
if err != nil { if err != nil {
@ -57,6 +61,7 @@ func NewClient(protocol, hostname, username, password, adport string, interval t
return http.ErrUseLastResponse return http.ErrUseLastResponse
}, },
}, },
rdnsenabled: rdnsenabled,
} }
} }
@ -67,14 +72,14 @@ func (c *Client) Scrape() {
allstats := c.getStatistics() allstats := c.getStatistics()
//Set the metrics //Set the metrics
c.setMetrics(allstats.status, allstats.stats, allstats.logStats) c.setMetrics(allstats.status, allstats.stats, allstats.logStats, allstats.rdns)
log.Printf("New tick of statistics: %s", allstats.stats.ToString()) log.Printf("New tick of statistics: %s", allstats.stats.ToString())
} }
} }
// Function to set the prometheus metrics // Function to set the prometheus metrics
func (c *Client) setMetrics(status *Status, stats *Stats, logstats *LogStats) { func (c *Client) setMetrics(status *Status, stats *Stats, logstats *LogStats, rdns map[string]string) {
//Status //Status
var isRunning int = 0 var isRunning int = 0
if status.Running == true { if status.Running == true {
@ -110,7 +115,15 @@ func (c *Client) setMetrics(status *Status, stats *Stats, logstats *LogStats) {
for l := range stats.TopClients { for l := range stats.TopClients {
for source, value := range stats.TopClients[l] { for source, value := range stats.TopClients[l] {
if c.rdnsenabled && isValidIp(source) {
hostName, exists := rdns[source]
if exists {
metrics.TopClients.WithLabelValues(c.hostname, hostName).Set(float64(value))
continue
}
}
metrics.TopClients.WithLabelValues(c.hostname, source).Set(float64(value)) metrics.TopClients.WithLabelValues(c.hostname, source).Set(float64(value))
} }
} }
@ -181,6 +194,34 @@ func (c *Client) getStatistics() *AllStats {
allstats.stats = &stats allstats.stats = &stats
allstats.logStats = &logstats allstats.logStats = &logstats
if c.rdnsenabled {
var sb strings.Builder
for l := range stats.TopClients {
for source, _ := range stats.TopClients[l] {
sb.WriteString(fmt.Sprintf("ip%d=%s", l, source))
if l < len(stats.TopClients)-1 {
sb.WriteString("&")
}
}
}
rdnsURL := fmt.Sprintf(resolveRDNSURLPattern, c.protocol, c.hostname, c.port, sb.String())
body = c.MakeRequest(rdnsURL)
var results []map[string]interface{}
err = json.Unmarshal(body, &results)
if err != nil {
log.Println("Unable to unmarshal Reverse DNS", err)
}
rdnsData := make(map[string]string)
for _, result := range results {
for key := range result {
data := result[key].(map[string]interface{})
rdnsData[key] = data["name"].(string)
}
}
allstats.rdns = rdnsData
}
return &allstats return &allstats
} }
@ -227,3 +268,11 @@ func GetTlsConfig() *tls.Config {
InsecureSkipVerify: true, InsecureSkipVerify: true,
} }
} }
func isValidIp(ip string) bool {
if net.ParseIP(ip) == nil {
return false
} else {
return true
}
}

View File

@ -7,6 +7,7 @@ type AllStats struct {
status *Status status *Status
stats *Stats stats *Stats
logStats *LogStats logStats *LogStats
rdns map[string]string
} }
// Status struct is the Adguard statistics JSON API corresponding model. // Status struct is the Adguard statistics JSON API corresponding model.

View File

@ -26,14 +26,14 @@ func main() {
metrics.Init() metrics.Init()
initAdguardClient(conf.AdguardProtocol, conf.AdguardHostname, conf.AdguardUsername, conf.AdguardPassword, conf.AdguardPort, conf.Interval, conf.LogLimit) initAdguardClient(conf.AdguardProtocol, conf.AdguardHostname, conf.AdguardUsername, conf.AdguardPassword, conf.AdguardPort, conf.Interval, conf.LogLimit, conf.RDnsEnabled)
initHttpServer(conf.ServerPort) initHttpServer(conf.ServerPort)
handleExitSignal() handleExitSignal()
} }
func initAdguardClient(protocol, hostname, username, password, port string, interval time.Duration, logLimit string) { func initAdguardClient(protocol, hostname, username, password, port string, interval time.Duration, logLimit string, rdnsenabled bool) {
client := adguard.NewClient(protocol, hostname, username, password, port, interval, logLimit) client := adguard.NewClient(protocol, hostname, username, password, port, interval, logLimit, rdnsenabled)
go client.Scrape() go client.Scrape()
} }