glance/internal/feed/adguard.go

121 lines
3.1 KiB
Go
Raw Normal View History

2024-08-23 00:11:45 +02:00
package feed
import (
"net/http"
"strings"
)
type adguardStatsResponse struct {
TotalQueries int `json:"num_dns_queries"`
QueriesSeries []int `json:"dns_queries"`
BlockedQueries int `json:"num_blocked_filtering"`
BlockedSeries []int `json:"blocked_filtering"`
ResponseTime float64 `json:"avg_processing_time"`
TopBlockedDomains []map[string]int `json:"top_blocked_domains"`
}
func FetchAdguardStats(instanceURL, username, password string) (*DNSStats, error) {
requestURL := strings.TrimRight(instanceURL, "/") + "/control/stats"
request, err := http.NewRequest("GET", requestURL, nil)
if err != nil {
return nil, err
}
request.SetBasicAuth(username, password)
responseJson, err := decodeJsonFromRequest[adguardStatsResponse](defaultClient, request)
if err != nil {
return nil, err
}
2024-09-10 06:34:56 +02:00
var topBlockedDomainsCount = min(len(responseJson.TopBlockedDomains), 5)
2024-08-23 00:11:45 +02:00
stats := &DNSStats{
2024-09-10 06:34:56 +02:00
TotalQueries: responseJson.TotalQueries,
BlockedQueries: responseJson.BlockedQueries,
ResponseTime: int(responseJson.ResponseTime * 1000),
TopBlockedDomains: make([]DNSStatsBlockedDomain, 0, topBlockedDomainsCount),
2024-08-23 00:11:45 +02:00
}
if stats.TotalQueries <= 0 {
return stats, nil
}
stats.BlockedPercent = int(float64(responseJson.BlockedQueries) / float64(responseJson.TotalQueries) * 100)
for i := 0; i < topBlockedDomainsCount; i++ {
domain := responseJson.TopBlockedDomains[i]
var firstDomain string
for k := range domain {
firstDomain = k
break
}
if firstDomain == "" {
continue
}
stats.TopBlockedDomains = append(stats.TopBlockedDomains, DNSStatsBlockedDomain{
2024-09-10 06:34:56 +02:00
Domain: firstDomain,
2024-08-23 00:11:45 +02:00
})
2024-09-10 06:34:56 +02:00
if stats.BlockedQueries > 0 {
stats.TopBlockedDomains[i].PercentBlocked = int(float64(domain[firstDomain]) / float64(responseJson.BlockedQueries) * 100)
}
2024-08-23 00:11:45 +02:00
}
2024-09-10 06:34:56 +02:00
queriesSeries := responseJson.QueriesSeries
blockedSeries := responseJson.BlockedSeries
const bars = 8
const hoursSpan = 24
const hoursPerBar int = hoursSpan / bars
if len(queriesSeries) > hoursSpan {
queriesSeries = queriesSeries[len(queriesSeries)-hoursSpan:]
} else if len(queriesSeries) < hoursSpan {
queriesSeries = append(make([]int, hoursSpan-len(queriesSeries)), queriesSeries...)
}
if len(blockedSeries) > hoursSpan {
blockedSeries = blockedSeries[len(blockedSeries)-hoursSpan:]
} else if len(blockedSeries) < hoursSpan {
blockedSeries = append(make([]int, hoursSpan-len(blockedSeries)), blockedSeries...)
2024-08-23 00:11:45 +02:00
}
maxQueriesInSeries := 0
2024-09-10 06:34:56 +02:00
for i := 0; i < bars; i++ {
2024-08-23 00:11:45 +02:00
queries := 0
blocked := 0
2024-09-10 06:34:56 +02:00
for j := 0; j < hoursPerBar; j++ {
queries += queriesSeries[i*hoursPerBar+j]
blocked += blockedSeries[i*hoursPerBar+j]
2024-08-23 00:11:45 +02:00
}
stats.Series[i] = DNSStatsSeries{
2024-09-10 06:34:56 +02:00
Queries: queries,
Blocked: blocked,
}
if queries > 0 {
stats.Series[i].PercentBlocked = int(float64(blocked) / float64(queries) * 100)
2024-08-23 00:11:45 +02:00
}
if queries > maxQueriesInSeries {
maxQueriesInSeries = queries
}
}
2024-09-10 06:34:56 +02:00
for i := 0; i < bars; i++ {
2024-08-23 00:11:45 +02:00
stats.Series[i].PercentTotal = int(float64(stats.Series[i].Queries) / float64(maxQueriesInSeries) * 100)
}
return stats, nil
}