Merge branch 'master' into ADG-9415

This commit is contained in:
Ildar Kamalov
2025-02-06 12:22:37 +03:00
8 changed files with 63 additions and 29 deletions

View File

@@ -18,6 +18,16 @@ See also the [v0.107.57 GitHub milestone][ms-v0.107.57].
NOTE: Add new changes BELOW THIS COMMENT. NOTE: Add new changes BELOW THIS COMMENT.
--> -->
### Changed
- The *Fastest IP adddress* upstream mode now collects statistics for the all upstream DNS servers.
### Fixed
- The formatting of large numbers in the upstream table and query log ([#7590]).
[#7590]: https://github.com/AdguardTeam/AdGuardHome/issues/7590
<!-- <!--
NOTE: Add new changes ABOVE THIS COMMENT. NOTE: Add new changes ABOVE THIS COMMENT.
--> -->

View File

@@ -10,6 +10,7 @@ import Card from '../ui/Card';
import DomainCell from './DomainCell'; import DomainCell from './DomainCell';
import { DASHBOARD_TABLES_DEFAULT_PAGE_SIZE, TABLES_MIN_ROWS } from '../../helpers/constants'; import { DASHBOARD_TABLES_DEFAULT_PAGE_SIZE, TABLES_MIN_ROWS } from '../../helpers/constants';
import { formatNumber } from '../../helpers/helpers';
interface TimeCellProps { interface TimeCellProps {
value?: string | number; value?: string | number;
@@ -20,7 +21,7 @@ const TimeCell = ({ value }: TimeCellProps) => {
return ''; return '';
} }
const valueInMilliseconds = round(Number(value) * 1000); const valueInMilliseconds = formatNumber(round(Number(value) * 1000));
return ( return (
<div className="logs__row o-hidden"> <div className="logs__row o-hidden">

View File

@@ -453,7 +453,7 @@ export const getParamsForClientsSearch = (data: any, param: any, additionalParam
}); });
return { return {
clients: Array.from(clients).map(id => ({ id })), clients: Array.from(clients).map((id) => ({ id })),
}; };
}; };
@@ -670,9 +670,16 @@ export const countClientsStatistics = (ids: any, autoClients: any) => {
* @param {function} t translate * @param {function} t translate
* @returns {string} * @returns {string}
*/ */
export const formatElapsedMs = (elapsedMs: any, t: any) => { export const formatElapsedMs = (elapsedMs: string, t: (key: string) => string) => {
const formattedElapsedMs = parseInt(elapsedMs, 10) || parseFloat(elapsedMs).toFixed(2); const parsedElapsedMs = parseInt(elapsedMs, 10);
return `${formattedElapsedMs} ${t('milliseconds_abbreviation')}`;
if (Number.isNaN(parsedElapsedMs)) {
return elapsedMs;
}
const formattedMs = formatNumber(parsedElapsedMs);
return `${formattedMs} ${t('milliseconds_abbreviation')}`;
}; };
/** /**

2
go.mod
View File

@@ -3,7 +3,7 @@ module github.com/AdguardTeam/AdGuardHome
go 1.23.5 go 1.23.5
require ( require (
github.com/AdguardTeam/dnsproxy v0.73.5 github.com/AdguardTeam/dnsproxy v0.75.0
github.com/AdguardTeam/golibs v0.31.0 github.com/AdguardTeam/golibs v0.31.0
github.com/AdguardTeam/urlfilter v0.20.0 github.com/AdguardTeam/urlfilter v0.20.0
github.com/NYTimes/gziphandler v1.1.1 github.com/NYTimes/gziphandler v1.1.1

4
go.sum
View File

@@ -1,5 +1,5 @@
github.com/AdguardTeam/dnsproxy v0.73.5 h1:3EiVaTfmuW6PcJGbqloR6ZdHACsrYkm9z0eH8ZQTZnQ= github.com/AdguardTeam/dnsproxy v0.75.0 h1:v8/Oq/xPYzNoALR7SEUZEIbKmjnPcXLVhJLFVbrozEc=
github.com/AdguardTeam/dnsproxy v0.73.5/go.mod h1:Oqw+k7LyjDObfYzXYCkpgtirbzbUrmotr92jrb3N09I= github.com/AdguardTeam/dnsproxy v0.75.0/go.mod h1:O2qoXwF4BUBFui7OMUiWSYwapEDcYxKWeur4+jfy9nM=
github.com/AdguardTeam/golibs v0.31.0 h1:Z0oPfLTLw6iZmpE58dePy2Bel0MaX+lnDwtFEE5EmIo= github.com/AdguardTeam/golibs v0.31.0 h1:Z0oPfLTLw6iZmpE58dePy2Bel0MaX+lnDwtFEE5EmIo=
github.com/AdguardTeam/golibs v0.31.0/go.mod h1:wIkZ9o2UnppeW6/YD7yJB71dYbMhiuC1Fh/I2ElW7GQ= github.com/AdguardTeam/golibs v0.31.0/go.mod h1:wIkZ9o2UnppeW6/YD7yJB71dYbMhiuC1Fh/I2ElW7GQ=
github.com/AdguardTeam/urlfilter v0.20.0 h1:X32qiuVCVd8WDYCEsbdZKfXMzwdVqrdulamtUi4rmzs= github.com/AdguardTeam/urlfilter v0.20.0 h1:X32qiuVCVd8WDYCEsbdZKfXMzwdVqrdulamtUi4rmzs=

View File

@@ -122,9 +122,14 @@ func (s *Server) logQuery(dctx *dnsContext, ip net.IP, processingTime time.Durat
if pctx.Upstream != nil { if pctx.Upstream != nil {
p.Upstream = pctx.Upstream.Address() p.Upstream = pctx.Upstream.Address()
} else if cachedUps := pctx.CachedUpstreamAddr; cachedUps != "" { }
p.Upstream = pctx.CachedUpstreamAddr
p.Cached = true if qs := pctx.QueryStatistics(); qs != nil {
ms := qs.Main()
if len(ms) == 1 && ms[0].IsCached {
p.Upstream = ms[0].Address
p.Cached = true
}
} }
s.queryLog.Add(p) s.queryLog.Add(p)
@@ -134,15 +139,18 @@ func (s *Server) logQuery(dctx *dnsContext, ip net.IP, processingTime time.Durat
func (s *Server) updateStats(dctx *dnsContext, clientIP string, processingTime time.Duration) { func (s *Server) updateStats(dctx *dnsContext, clientIP string, processingTime time.Duration) {
pctx := dctx.proxyCtx pctx := dctx.proxyCtx
var upstreamStats []*proxy.UpstreamStatistics
qs := pctx.QueryStatistics()
if qs != nil {
upstreamStats = append(upstreamStats, qs.Main()...)
upstreamStats = append(upstreamStats, qs.Fallback()...)
}
e := &stats.Entry{ e := &stats.Entry{
UpstreamStats: upstreamStats,
Domain: aghnet.NormalizeDomain(pctx.Req.Question[0].Name), Domain: aghnet.NormalizeDomain(pctx.Req.Question[0].Name),
Result: stats.RNotFiltered, Result: stats.RNotFiltered,
ProcessingTime: processingTime, ProcessingTime: processingTime,
UpstreamTime: pctx.QueryDuration,
}
if pctx.Upstream != nil {
e.Upstream = pctx.Upstream.Address()
} }
if clientID := dctx.clientID; clientID != "" { if clientID := dctx.clientID; clientID != "" {

View File

@@ -13,6 +13,7 @@ import (
"github.com/AdguardTeam/AdGuardHome/internal/aghnet" "github.com/AdguardTeam/AdGuardHome/internal/aghnet"
"github.com/AdguardTeam/AdGuardHome/internal/stats" "github.com/AdguardTeam/AdGuardHome/internal/stats"
"github.com/AdguardTeam/dnsproxy/proxy"
"github.com/AdguardTeam/golibs/logutil/slogutil" "github.com/AdguardTeam/golibs/logutil/slogutil"
"github.com/AdguardTeam/golibs/netutil" "github.com/AdguardTeam/golibs/netutil"
"github.com/AdguardTeam/golibs/testutil" "github.com/AdguardTeam/golibs/testutil"
@@ -78,15 +79,19 @@ func TestStats(t *testing.T) {
Client: cliIPStr, Client: cliIPStr,
Result: stats.RFiltered, Result: stats.RFiltered,
ProcessingTime: time.Microsecond * 123456, ProcessingTime: time.Microsecond * 123456,
Upstream: respUpstream, UpstreamStats: []*proxy.UpstreamStatistics{{
UpstreamTime: time.Microsecond * 222222, Address: respUpstream,
QueryDuration: time.Microsecond * 222222,
}},
}, { }, {
Domain: reqDomain, Domain: reqDomain,
Client: cliIPStr, Client: cliIPStr,
Result: stats.RNotFiltered, Result: stats.RNotFiltered,
ProcessingTime: time.Microsecond * 123456, ProcessingTime: time.Microsecond * 123456,
Upstream: respUpstream, UpstreamStats: []*proxy.UpstreamStatistics{{
UpstreamTime: time.Microsecond * 222222, Address: respUpstream,
QueryDuration: time.Microsecond * 222222,
}},
}} }}
wantData := &stats.StatsResp{ wantData := &stats.StatsResp{

View File

@@ -10,6 +10,7 @@ import (
"time" "time"
"github.com/AdguardTeam/AdGuardHome/internal/aghnet" "github.com/AdguardTeam/AdGuardHome/internal/aghnet"
"github.com/AdguardTeam/dnsproxy/proxy"
"github.com/AdguardTeam/golibs/errors" "github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/logutil/slogutil" "github.com/AdguardTeam/golibs/logutil/slogutil"
"go.etcd.io/bbolt" "go.etcd.io/bbolt"
@@ -62,8 +63,9 @@ type Entry struct {
// Domain is the domain name requested. // Domain is the domain name requested.
Domain string Domain string
// Upstream is the upstream DNS server. // UpstreamStats contains the DNS query statistics for both the upstream and
Upstream string // fallback DNS servers.
UpstreamStats []*proxy.UpstreamStatistics
// Result is the result of processing the request. // Result is the result of processing the request.
Result Result Result Result
@@ -71,9 +73,6 @@ type Entry struct {
// ProcessingTime is the duration of the request processing from the start // ProcessingTime is the duration of the request processing from the start
// of the request including timeouts. // of the request including timeouts.
ProcessingTime time.Duration ProcessingTime time.Duration
// UpstreamTime is the duration of the successful request to the upstream.
UpstreamTime time.Duration
} }
// validate returns an error if entry is not valid. // validate returns an error if entry is not valid.
@@ -329,10 +328,14 @@ func (u *unit) add(e *Entry) {
u.timeSum += pt u.timeSum += pt
u.nTotal++ u.nTotal++
if e.Upstream != "" { for _, s := range e.UpstreamStats {
u.upstreamsResponses[e.Upstream]++ if s.IsCached || s.Error != nil {
ut := uint64(e.UpstreamTime.Microseconds()) continue
u.upstreamsTimeSum[e.Upstream] += ut }
addr := s.Address
u.upstreamsResponses[addr]++
u.upstreamsTimeSum[addr] += uint64(s.QueryDuration.Microseconds())
} }
} }