diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9c216f35..923c6e4e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,6 +18,16 @@ See also the [v0.107.57 GitHub milestone][ms-v0.107.57].
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
+
diff --git a/client/src/components/Dashboard/UpstreamAvgTime.tsx b/client/src/components/Dashboard/UpstreamAvgTime.tsx
index 48ed9e6a..8f5b4cab 100644
--- a/client/src/components/Dashboard/UpstreamAvgTime.tsx
+++ b/client/src/components/Dashboard/UpstreamAvgTime.tsx
@@ -10,6 +10,7 @@ import Card from '../ui/Card';
import DomainCell from './DomainCell';
import { DASHBOARD_TABLES_DEFAULT_PAGE_SIZE, TABLES_MIN_ROWS } from '../../helpers/constants';
+import { formatNumber } from '../../helpers/helpers';
interface TimeCellProps {
value?: string | number;
@@ -20,7 +21,7 @@ const TimeCell = ({ value }: TimeCellProps) => {
return '–';
}
- const valueInMilliseconds = round(Number(value) * 1000);
+ const valueInMilliseconds = formatNumber(round(Number(value) * 1000));
return (
diff --git a/client/src/helpers/helpers.tsx b/client/src/helpers/helpers.tsx
index fa8d1886..c92d5422 100644
--- a/client/src/helpers/helpers.tsx
+++ b/client/src/helpers/helpers.tsx
@@ -453,7 +453,7 @@ export const getParamsForClientsSearch = (data: any, param: any, additionalParam
});
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
* @returns {string}
*/
-export const formatElapsedMs = (elapsedMs: any, t: any) => {
- const formattedElapsedMs = parseInt(elapsedMs, 10) || parseFloat(elapsedMs).toFixed(2);
- return `${formattedElapsedMs} ${t('milliseconds_abbreviation')}`;
+export const formatElapsedMs = (elapsedMs: string, t: (key: string) => string) => {
+ const parsedElapsedMs = parseInt(elapsedMs, 10);
+
+ if (Number.isNaN(parsedElapsedMs)) {
+ return elapsedMs;
+ }
+
+ const formattedMs = formatNumber(parsedElapsedMs);
+
+ return `${formattedMs} ${t('milliseconds_abbreviation')}`;
};
/**
diff --git a/go.mod b/go.mod
index 1ed09910..7e2d5a55 100644
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,7 @@ module github.com/AdguardTeam/AdGuardHome
go 1.23.5
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/urlfilter v0.20.0
github.com/NYTimes/gziphandler v1.1.1
diff --git a/go.sum b/go.sum
index ed6ca788..d93deb23 100644
--- a/go.sum
+++ b/go.sum
@@ -1,5 +1,5 @@
-github.com/AdguardTeam/dnsproxy v0.73.5 h1:3EiVaTfmuW6PcJGbqloR6ZdHACsrYkm9z0eH8ZQTZnQ=
-github.com/AdguardTeam/dnsproxy v0.73.5/go.mod h1:Oqw+k7LyjDObfYzXYCkpgtirbzbUrmotr92jrb3N09I=
+github.com/AdguardTeam/dnsproxy v0.75.0 h1:v8/Oq/xPYzNoALR7SEUZEIbKmjnPcXLVhJLFVbrozEc=
+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/go.mod h1:wIkZ9o2UnppeW6/YD7yJB71dYbMhiuC1Fh/I2ElW7GQ=
github.com/AdguardTeam/urlfilter v0.20.0 h1:X32qiuVCVd8WDYCEsbdZKfXMzwdVqrdulamtUi4rmzs=
diff --git a/internal/dnsforward/stats.go b/internal/dnsforward/stats.go
index ffcbc6ef..50818b40 100644
--- a/internal/dnsforward/stats.go
+++ b/internal/dnsforward/stats.go
@@ -122,9 +122,14 @@ func (s *Server) logQuery(dctx *dnsContext, ip net.IP, processingTime time.Durat
if pctx.Upstream != nil {
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)
@@ -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) {
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{
+ UpstreamStats: upstreamStats,
Domain: aghnet.NormalizeDomain(pctx.Req.Question[0].Name),
Result: stats.RNotFiltered,
ProcessingTime: processingTime,
- UpstreamTime: pctx.QueryDuration,
- }
-
- if pctx.Upstream != nil {
- e.Upstream = pctx.Upstream.Address()
}
if clientID := dctx.clientID; clientID != "" {
diff --git a/internal/stats/stats_test.go b/internal/stats/stats_test.go
index dbf857d6..06aa36f3 100644
--- a/internal/stats/stats_test.go
+++ b/internal/stats/stats_test.go
@@ -13,6 +13,7 @@ import (
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
"github.com/AdguardTeam/AdGuardHome/internal/stats"
+ "github.com/AdguardTeam/dnsproxy/proxy"
"github.com/AdguardTeam/golibs/logutil/slogutil"
"github.com/AdguardTeam/golibs/netutil"
"github.com/AdguardTeam/golibs/testutil"
@@ -78,15 +79,19 @@ func TestStats(t *testing.T) {
Client: cliIPStr,
Result: stats.RFiltered,
ProcessingTime: time.Microsecond * 123456,
- Upstream: respUpstream,
- UpstreamTime: time.Microsecond * 222222,
+ UpstreamStats: []*proxy.UpstreamStatistics{{
+ Address: respUpstream,
+ QueryDuration: time.Microsecond * 222222,
+ }},
}, {
Domain: reqDomain,
Client: cliIPStr,
Result: stats.RNotFiltered,
ProcessingTime: time.Microsecond * 123456,
- Upstream: respUpstream,
- UpstreamTime: time.Microsecond * 222222,
+ UpstreamStats: []*proxy.UpstreamStatistics{{
+ Address: respUpstream,
+ QueryDuration: time.Microsecond * 222222,
+ }},
}}
wantData := &stats.StatsResp{
diff --git a/internal/stats/unit.go b/internal/stats/unit.go
index cef7fca2..5eef6f3c 100644
--- a/internal/stats/unit.go
+++ b/internal/stats/unit.go
@@ -10,6 +10,7 @@ import (
"time"
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
+ "github.com/AdguardTeam/dnsproxy/proxy"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/logutil/slogutil"
"go.etcd.io/bbolt"
@@ -62,8 +63,9 @@ type Entry struct {
// Domain is the domain name requested.
Domain string
- // Upstream is the upstream DNS server.
- Upstream string
+ // UpstreamStats contains the DNS query statistics for both the upstream and
+ // fallback DNS servers.
+ UpstreamStats []*proxy.UpstreamStatistics
// Result is the result of processing the request.
Result Result
@@ -71,9 +73,6 @@ type Entry struct {
// ProcessingTime is the duration of the request processing from the start
// of the request including timeouts.
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.
@@ -329,10 +328,14 @@ func (u *unit) add(e *Entry) {
u.timeSum += pt
u.nTotal++
- if e.Upstream != "" {
- u.upstreamsResponses[e.Upstream]++
- ut := uint64(e.UpstreamTime.Microseconds())
- u.upstreamsTimeSum[e.Upstream] += ut
+ for _, s := range e.UpstreamStats {
+ if s.IsCached || s.Error != nil {
+ continue
+ }
+
+ addr := s.Address
+ u.upstreamsResponses[addr]++
+ u.upstreamsTimeSum[addr] += uint64(s.QueryDuration.Microseconds())
}
}