From 97684368b94c0a50460d727030770aa94fb3e771 Mon Sep 17 00:00:00 2001 From: Simon Zolin Date: Fri, 6 Sep 2019 15:42:21 +0300 Subject: [PATCH 1/5] - stats: use --workdir --- home/dns.go | 7 ++++--- stats/stats.go | 2 +- stats/stats_test.go | 4 ++-- stats/stats_unit.go | 6 +++--- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/home/dns.go b/home/dns.go index c00ddf51..49b5d0a7 100644 --- a/home/dns.go +++ b/home/dns.go @@ -4,6 +4,7 @@ import ( "fmt" "net" "os" + "path/filepath" "sync" "github.com/AdguardTeam/AdGuardHome/dnsfilter" @@ -34,9 +35,9 @@ func initDNSServer(baseDir string) { log.Fatalf("Cannot create DNS data dir at %s: %s", baseDir, err) } - config.stats = stats.New("./data/stats.db", int(config.DNS.StatsInterval), nil) - if config.stats == nil { - log.Fatal("config.stats == nil") + config.stats, err = stats.New(filepath.Join(baseDir, "stats.db"), int(config.DNS.StatsInterval), nil) + if err != nil { + log.Fatal("Couldn't initialize statistics module") } config.dnsServer = dnsforward.NewServer(baseDir, config.stats) diff --git a/stats/stats.go b/stats/stats.go index 2542b16d..d33ee42d 100644 --- a/stats/stats.go +++ b/stats/stats.go @@ -12,7 +12,7 @@ type unitIDCallback func() int // filename: DB file name // limit: time limit (in days) // unitID: user function to get the current unit ID. If nil, the current time hour is used. -func New(filename string, limit int, unitID unitIDCallback) Stats { +func New(filename string, limit int, unitID unitIDCallback) (Stats, error) { return createObject(filename, limit, unitID) } diff --git a/stats/stats_test.go b/stats/stats_test.go index 45b06520..d2e14189 100644 --- a/stats/stats_test.go +++ b/stats/stats_test.go @@ -26,7 +26,7 @@ func UIntArrayEquals(a []uint, b []uint) bool { } func TestStats(t *testing.T) { - s := New("./stats.db", 1, nil) + s, _ := New("./stats.db", 1, nil) e := Entry{} @@ -87,7 +87,7 @@ func TestLargeNumbers(t *testing.T) { // log.SetLevel(log.DEBUG) fn := "./stats.db" os.Remove(fn) - s := New(fn, 1, newID) + s, _ := New(fn, 1, newID) e := Entry{} n := 1000 // number of distinct clients and domains every hour diff --git a/stats/stats_unit.go b/stats/stats_unit.go index 1cc69324..faa30fdb 100644 --- a/stats/stats_unit.go +++ b/stats/stats_unit.go @@ -62,7 +62,7 @@ type unitDB struct { TimeAvg uint // usec } -func createObject(filename string, limitDays int, unitID unitIDCallback) *statsCtx { +func createObject(filename string, limitDays int, unitID unitIDCallback) (*statsCtx, error) { s := statsCtx{} s.limit = limitDays * 24 s.filename = filename @@ -72,7 +72,7 @@ func createObject(filename string, limitDays int, unitID unitIDCallback) *statsC } if !s.dbOpen() { - return nil + return nil, fmt.Errorf("open database") } id := s.unitID() @@ -116,7 +116,7 @@ func createObject(filename string, limitDays int, unitID unitIDCallback) *statsC go s.periodicFlush() log.Debug("Stats: initialized") - return &s + return &s, nil } func (s *statsCtx) dbOpen() bool { From 8a2aa57e241c6855b624c16e2a45f7844062b01f Mon Sep 17 00:00:00 2001 From: Simon Zolin Date: Tue, 10 Sep 2019 13:52:19 +0300 Subject: [PATCH 2/5] - /stats_config: write config --- home/control_stats.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/home/control_stats.go b/home/control_stats.go index 710eb577..5adb681a 100644 --- a/home/control_stats.go +++ b/home/control_stats.go @@ -44,6 +44,8 @@ func handleStatsConfig(w http.ResponseWriter, r *http.Request) { } config.DNS.StatsInterval = reqData.Interval + _ = config.write() + config.stats.Configure(int(config.DNS.StatsInterval)) returnOK(w) From 04e2566e9e968f299e134e812ca88d24073de9ff Mon Sep 17 00:00:00 2001 From: Simon Zolin Date: Tue, 10 Sep 2019 17:59:10 +0300 Subject: [PATCH 3/5] * stats: use uint32 or uint64 integer values, not int --- dnsforward/dnsforward.go | 2 +- home/config.go | 2 +- home/control_stats.go | 4 +- home/dns.go | 3 +- stats/stats.go | 6 +- stats/stats_test.go | 40 ++++++------ stats/stats_unit.go | 136 +++++++++++++++++++-------------------- 7 files changed, 97 insertions(+), 96 deletions(-) diff --git a/dnsforward/dnsforward.go b/dnsforward/dnsforward.go index 29146843..0fffd0a5 100644 --- a/dnsforward/dnsforward.go +++ b/dnsforward/dnsforward.go @@ -496,7 +496,7 @@ func (s *Server) updateStats(d *proxy.DNSContext, elapsed time.Duration, res dns case *net.TCPAddr: e.Client = addr.IP } - e.Time = uint(elapsed / 1000) + e.Time = uint32(elapsed / 1000) switch res.Reason { case dnsfilter.NotFilteredNotFound: diff --git a/home/config.go b/home/config.go index b3a62efe..4edc168f 100644 --- a/home/config.go +++ b/home/config.go @@ -110,7 +110,7 @@ type dnsConfig struct { Port int `yaml:"port"` // time interval for statistics (in days) - StatsInterval uint `yaml:"statistics_interval"` + StatsInterval uint32 `yaml:"statistics_interval"` dnsforward.FilteringConfig `yaml:",inline"` diff --git a/home/control_stats.go b/home/control_stats.go index 5adb681a..67b26f6b 100644 --- a/home/control_stats.go +++ b/home/control_stats.go @@ -9,7 +9,7 @@ import ( ) type statsConfig struct { - Interval uint `json:"interval"` + Interval uint32 `json:"interval"` } // Get stats configuration @@ -89,6 +89,6 @@ func RegisterStatsHandlers() { httpRegister(http.MethodGet, "/control/stats_info", handleStatsInfo) } -func checkStatsInterval(i uint) bool { +func checkStatsInterval(i uint32) bool { return i == 1 || i == 7 || i == 30 || i == 90 } diff --git a/home/dns.go b/home/dns.go index 49b5d0a7..b1d1b0ca 100644 --- a/home/dns.go +++ b/home/dns.go @@ -35,7 +35,8 @@ func initDNSServer(baseDir string) { log.Fatalf("Cannot create DNS data dir at %s: %s", baseDir, err) } - config.stats, err = stats.New(filepath.Join(baseDir, "stats.db"), int(config.DNS.StatsInterval), nil) + statsDBFilename := filepath.Join(baseDir, "stats.db") + config.stats, err = stats.New(statsDBFilename, config.DNS.StatsInterval, nil) if err != nil { log.Fatal("Couldn't initialize statistics module") } diff --git a/stats/stats.go b/stats/stats.go index d33ee42d..b6883869 100644 --- a/stats/stats.go +++ b/stats/stats.go @@ -6,13 +6,13 @@ import ( "net" ) -type unitIDCallback func() int +type unitIDCallback func() uint32 // New - create object // filename: DB file name // limit: time limit (in days) // unitID: user function to get the current unit ID. If nil, the current time hour is used. -func New(filename string, limit int, unitID unitIDCallback) (Stats, error) { +func New(filename string, limit uint32, unitID unitIDCallback) (Stats, error) { return createObject(filename, limit, unitID) } @@ -64,5 +64,5 @@ type Entry struct { Domain string Client net.IP Result Result - Time uint // processing time (msec) + Time uint32 // processing time (msec) } diff --git a/stats/stats_test.go b/stats/stats_test.go index d2e14189..70437689 100644 --- a/stats/stats_test.go +++ b/stats/stats_test.go @@ -11,7 +11,7 @@ import ( "github.com/stretchr/testify/assert" ) -func UIntArrayEquals(a []uint, b []uint) bool { +func UIntArrayEquals(a []uint64, b []uint64) bool { if len(a) != len(b) { return false } @@ -43,32 +43,32 @@ func TestStats(t *testing.T) { s.Update(e) d := s.GetData(Hours) - a := []uint{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2} - assert.True(t, UIntArrayEquals(d["dns_queries"].([]uint), a)) + a := []uint64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2} + assert.True(t, UIntArrayEquals(d["dns_queries"].([]uint64), a)) - a = []uint{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1} - assert.True(t, UIntArrayEquals(d["blocked_filtering"].([]uint), a)) + a = []uint64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1} + assert.True(t, UIntArrayEquals(d["blocked_filtering"].([]uint64), a)) - a = []uint{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - assert.True(t, UIntArrayEquals(d["replaced_safebrowsing"].([]uint), a)) + a = []uint64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + assert.True(t, UIntArrayEquals(d["replaced_safebrowsing"].([]uint64), a)) - a = []uint{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - assert.True(t, UIntArrayEquals(d["replaced_parental"].([]uint), a)) + a = []uint64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + assert.True(t, UIntArrayEquals(d["replaced_parental"].([]uint64), a)) - m := d["top_queried_domains"].([]map[string]uint) + m := d["top_queried_domains"].([]map[string]uint64) assert.True(t, m[0]["domain"] == 1) - m = d["top_blocked_domains"].([]map[string]uint) + m = d["top_blocked_domains"].([]map[string]uint64) assert.True(t, m[0]["domain"] == 1) - m = d["top_clients"].([]map[string]uint) + m = d["top_clients"].([]map[string]uint64) assert.True(t, m[0]["127.0.0.1"] == 2) - assert.True(t, d["num_dns_queries"].(uint) == 2) - assert.True(t, d["num_blocked_filtering"].(uint) == 1) - assert.True(t, d["num_replaced_safebrowsing"].(uint) == 0) - assert.True(t, d["num_replaced_safesearch"].(uint) == 0) - assert.True(t, d["num_replaced_parental"].(uint) == 0) + assert.True(t, d["num_dns_queries"].(uint64) == 2) + assert.True(t, d["num_blocked_filtering"].(uint64) == 1) + assert.True(t, d["num_replaced_safebrowsing"].(uint64) == 0) + assert.True(t, d["num_replaced_safesearch"].(uint64) == 0) + assert.True(t, d["num_replaced_parental"].(uint64) == 0) assert.True(t, d["avg_processing_time"].(float64) == 0.123456) s.Clear() @@ -79,9 +79,9 @@ func TestStats(t *testing.T) { func TestLargeNumbers(t *testing.T) { var hour int32 hour = 1 - newID := func() int { + newID := func() uint32 { // use "atomic" to make Go race detector happy - return int(atomic.LoadInt32(&hour)) + return uint32(atomic.LoadInt32(&hour)) } // log.SetLevel(log.DEBUG) @@ -108,7 +108,7 @@ func TestLargeNumbers(t *testing.T) { } d := s.GetData(Hours) - assert.True(t, d["num_dns_queries"].(uint) == uint(int(hour)*n)) + assert.True(t, d["num_dns_queries"].(uint64) == uint64(int(hour)*n)) s.Close() os.Remove(fn) diff --git a/stats/stats_unit.go b/stats/stats_unit.go index faa30fdb..e4eba676 100644 --- a/stats/stats_unit.go +++ b/stats/stats_unit.go @@ -21,7 +21,7 @@ const ( // statsCtx - global context type statsCtx struct { - limit int // maximum time we need to keep data for (in hours) + limit uint32 // maximum time we need to keep data for (in hours) filename string // database file name unitID unitIDCallback // user function which returns the current unit ID db *bolt.DB @@ -32,37 +32,37 @@ type statsCtx struct { // data for 1 time unit type unit struct { - id int // unit ID. Default: absolute hour since Jan 1, 1970 + id uint32 // unit ID. Default: absolute hour since Jan 1, 1970 - nTotal int // total requests - nResult []int // number of requests per one result - timeSum int // sum of processing time of all requests (usec) + nTotal uint64 // total requests + nResult []uint64 // number of requests per one result + timeSum uint64 // sum of processing time of all requests (usec) // top: - domains map[string]int // number of requests per domain - blockedDomains map[string]int // number of blocked requests per domain - clients map[string]int // number of requests per client + domains map[string]uint64 // number of requests per domain + blockedDomains map[string]uint64 // number of blocked requests per domain + clients map[string]uint64 // number of requests per client } // name-count pair type countPair struct { Name string - Count uint + Count uint64 } // structure for storing data in file type unitDB struct { - NTotal uint - NResult []uint + NTotal uint64 + NResult []uint64 Domains []countPair BlockedDomains []countPair Clients []countPair - TimeAvg uint // usec + TimeAvg uint32 // usec } -func createObject(filename string, limitDays int, unitID unitIDCallback) (*statsCtx, error) { +func createObject(filename string, limitDays uint32, unitID unitIDCallback) (*statsCtx, error) { s := statsCtx{} s.limit = limitDays * 24 s.filename = filename @@ -83,7 +83,7 @@ func createObject(filename string, limitDays int, unitID unitIDCallback) (*stats firstID := id - s.limit - 1 unitDel := 0 forEachBkt := func(name []byte, b *bolt.Bucket) error { - id := btoi(name) + id := uint32(btoi(name)) if id < firstID { err := tx.DeleteBucket(name) if err != nil { @@ -142,17 +142,17 @@ func (s *statsCtx) swapUnit(new *unit) *unit { } // Get unit ID for the current hour -func newUnitID() int { - return int(time.Now().Unix() / (60 * 60)) +func newUnitID() uint32 { + return uint32(time.Now().Unix() / (60 * 60)) } // Initialize a unit -func (s *statsCtx) initUnit(u *unit, id int) { +func (s *statsCtx) initUnit(u *unit, id uint32) { u.id = id - u.nResult = make([]int, rLast) - u.domains = make(map[string]int) - u.blockedDomains = make(map[string]int) - u.clients = make(map[string]int) + u.nResult = make([]uint64, rLast) + u.domains = make(map[string]uint64) + u.blockedDomains = make(map[string]uint64) + u.clients = make(map[string]uint64) } // Open a DB transaction @@ -182,20 +182,20 @@ func (s *statsCtx) commitTxn(tx *bolt.Tx) { } // Get unit name -func unitName(id int) []byte { - return itob(id) +func unitName(id uint32) []byte { + return itob(uint64(id)) } // Convert integer to 8-byte array (big endian) -func itob(v int) []byte { +func itob(v uint64) []byte { b := make([]byte, 8) - binary.BigEndian.PutUint64(b, uint64(v)) + binary.BigEndian.PutUint64(b, v) return b } // Convert 8-byte array (big endian) to integer -func btoi(b []byte) int { - return int(binary.BigEndian.Uint64(b)) +func btoi(b []byte) uint64 { + return binary.BigEndian.Uint64(b) } // Flush the current unit to DB and delete an old unit when a new hour is started @@ -235,7 +235,7 @@ func (s *statsCtx) periodicFlush() { } // Delete unit's data from file -func (s *statsCtx) deleteUnit(tx *bolt.Tx, id int) bool { +func (s *statsCtx) deleteUnit(tx *bolt.Tx, id uint32) bool { err := tx.DeleteBucket(unitName(id)) if err != nil { log.Tracef("bolt DeleteBucket: %s", err) @@ -245,12 +245,12 @@ func (s *statsCtx) deleteUnit(tx *bolt.Tx, id int) bool { return true } -func convertMapToArray(m map[string]int, max int) []countPair { +func convertMapToArray(m map[string]uint64, max int) []countPair { a := []countPair{} for k, v := range m { pair := countPair{} pair.Name = k - pair.Count = uint(v) + pair.Count = v a = append(a, pair) } less := func(i, j int) bool { @@ -266,22 +266,22 @@ func convertMapToArray(m map[string]int, max int) []countPair { return a[:max] } -func convertArrayToMap(a []countPair) map[string]int { - m := map[string]int{} +func convertArrayToMap(a []countPair) map[string]uint64 { + m := map[string]uint64{} for _, it := range a { - m[it.Name] = int(it.Count) + m[it.Name] = it.Count } return m } func serialize(u *unit) *unitDB { udb := unitDB{} - udb.NTotal = uint(u.nTotal) + udb.NTotal = u.nTotal for _, it := range u.nResult { - udb.NResult = append(udb.NResult, uint(it)) + udb.NResult = append(udb.NResult, it) } if u.nTotal != 0 { - udb.TimeAvg = uint(u.timeSum / u.nTotal) + udb.TimeAvg = uint32(u.timeSum / u.nTotal) } udb.Domains = convertMapToArray(u.domains, maxDomains) udb.BlockedDomains = convertMapToArray(u.blockedDomains, maxDomains) @@ -290,17 +290,17 @@ func serialize(u *unit) *unitDB { } func deserialize(u *unit, udb *unitDB) { - u.nTotal = int(udb.NTotal) + u.nTotal = udb.NTotal for _, it := range udb.NResult { u.nResult = append(u.nResult, int(it)) } u.domains = convertArrayToMap(udb.Domains) u.blockedDomains = convertArrayToMap(udb.BlockedDomains) u.clients = convertArrayToMap(udb.Clients) - u.timeSum = int(udb.TimeAvg) * u.nTotal + u.timeSum = uint64(udb.TimeAvg) * u.nTotal } -func (s *statsCtx) flushUnitToDB(tx *bolt.Tx, id int, udb *unitDB) bool { +func (s *statsCtx) flushUnitToDB(tx *bolt.Tx, id uint32, udb *unitDB) bool { log.Tracef("Flushing unit %d", id) bkt, err := tx.CreateBucketIfNotExists(unitName(id)) @@ -326,7 +326,7 @@ func (s *statsCtx) flushUnitToDB(tx *bolt.Tx, id int, udb *unitDB) bool { return true } -func (s *statsCtx) loadUnitFromDB(tx *bolt.Tx, id int) *unitDB { +func (s *statsCtx) loadUnitFromDB(tx *bolt.Tx, id uint32) *unitDB { bkt := tx.Bucket(unitName(id)) if bkt == nil { return nil @@ -347,10 +347,10 @@ func (s *statsCtx) loadUnitFromDB(tx *bolt.Tx, id int) *unitDB { return &udb } -func convertTopArray(a []countPair) []map[string]uint { - m := []map[string]uint{} +func convertTopArray(a []countPair) []map[string]uint64 { + m := []map[string]uint64{} for _, it := range a { - ent := map[string]uint{} + ent := map[string]uint64{} ent[it.Name] = it.Count m = append(m, ent) } @@ -361,7 +361,7 @@ func (s *statsCtx) Configure(limit int) { if limit < 0 { return } - s.limit = limit * 24 + s.limit = uint32(limit) * 24 log.Debug("Stats: set limit: %d", limit) } @@ -433,7 +433,7 @@ func (s *statsCtx) Update(e Entry) { } u.clients[client]++ - u.timeSum += int(e.Time) + u.timeSum += uint64(e.Time) u.nTotal++ s.unitLock.Unlock() } @@ -481,7 +481,7 @@ func (s *statsCtx) GetData(timeUnit TimeUnit) map[string]interface{} { u := s.loadUnitFromDB(tx, i) if u == nil { u = &unitDB{} - u.NResult = make([]uint, rLast) + u.NResult = make([]uint64, rLast) } units = append(units, u) } @@ -497,7 +497,7 @@ func (s *statsCtx) GetData(timeUnit TimeUnit) map[string]interface{} { } units = append(units, cu) - if len(units) != s.limit { + if len(units) != int(s.limit) { log.Fatalf("len(units) != s.limit: %d %d", len(units), s.limit) } @@ -506,16 +506,16 @@ func (s *statsCtx) GetData(timeUnit TimeUnit) map[string]interface{} { // 720 hours may span 31 days, so we skip data for the first day in this case firstDayID := (firstID + 24 - 1) / 24 * 24 // align_ceil(24) - a := []uint{} + a := []uint64{} if timeUnit == Hours { for _, u := range units { a = append(a, u.NTotal) } } else { - var sum uint + var sum uint64 id := firstDayID nextDayID := firstDayID + 24 - for i := firstDayID - firstID; i != len(units); i++ { + for i := firstDayID - firstID; int(i) != len(units); i++ { sum += units[i].NTotal if id == nextDayID { a = append(a, sum) @@ -527,22 +527,22 @@ func (s *statsCtx) GetData(timeUnit TimeUnit) map[string]interface{} { if id < nextDayID { a = append(a, sum) } - if len(a) != s.limit/24 { + if len(a) != int(s.limit/24) { log.Fatalf("len(a) != s.limit: %d %d", len(a), s.limit) } } d["dns_queries"] = a - a = []uint{} + a = []uint64{} if timeUnit == Hours { for _, u := range units { a = append(a, u.NResult[RFiltered]) } } else { - var sum uint + var sum uint64 id := firstDayID nextDayID := firstDayID + 24 - for i := firstDayID - firstID; i != len(units); i++ { + for i := firstDayID - firstID; int(i) != len(units); i++ { sum += units[i].NResult[RFiltered] if id == nextDayID { a = append(a, sum) @@ -557,16 +557,16 @@ func (s *statsCtx) GetData(timeUnit TimeUnit) map[string]interface{} { } d["blocked_filtering"] = a - a = []uint{} + a = []uint64{} if timeUnit == Hours { for _, u := range units { a = append(a, u.NResult[RSafeBrowsing]) } } else { - var sum uint + var sum uint64 id := firstDayID nextDayID := firstDayID + 24 - for i := firstDayID - firstID; i != len(units); i++ { + for i := firstDayID - firstID; int(i) != len(units); i++ { sum += units[i].NResult[RSafeBrowsing] if id == nextDayID { a = append(a, sum) @@ -581,16 +581,16 @@ func (s *statsCtx) GetData(timeUnit TimeUnit) map[string]interface{} { } d["replaced_safebrowsing"] = a - a = []uint{} + a = []uint64{} if timeUnit == Hours { for _, u := range units { a = append(a, u.NResult[RParental]) } } else { - var sum uint + var sum uint64 id := firstDayID nextDayID := firstDayID + 24 - for i := firstDayID - firstID; i != len(units); i++ { + for i := firstDayID - firstID; int(i) != len(units); i++ { sum += units[i].NResult[RParental] if id == nextDayID { a = append(a, sum) @@ -607,28 +607,28 @@ func (s *statsCtx) GetData(timeUnit TimeUnit) map[string]interface{} { // top counters: - m := map[string]int{} + m := map[string]uint64{} for _, u := range units { for _, it := range u.Domains { - m[it.Name] += int(it.Count) + m[it.Name] += it.Count } } a2 := convertMapToArray(m, maxDomains) d["top_queried_domains"] = convertTopArray(a2) - m = map[string]int{} + m = map[string]uint64{} for _, u := range units { for _, it := range u.BlockedDomains { - m[it.Name] += int(it.Count) + m[it.Name] += it.Count } } a2 = convertMapToArray(m, maxDomains) d["top_blocked_domains"] = convertTopArray(a2) - m = map[string]int{} + m = map[string]uint64{} for _, u := range units { for _, it := range u.Clients { - m[it.Name] += int(it.Count) + m[it.Name] += it.Count } } a2 = convertMapToArray(m, maxClients) @@ -637,8 +637,8 @@ func (s *statsCtx) GetData(timeUnit TimeUnit) map[string]interface{} { // total counters: sum := unitDB{} + sum.NResult = make([]uint64, rLast) timeN := 0 - sum.NResult = make([]uint, rLast) for _, u := range units { sum.NTotal += u.NTotal sum.TimeAvg += u.TimeAvg @@ -659,7 +659,7 @@ func (s *statsCtx) GetData(timeUnit TimeUnit) map[string]interface{} { avgTime := float64(0) if timeN != 0 { - avgTime = float64(sum.TimeAvg/uint(timeN)) / 1000000 + avgTime = float64(sum.TimeAvg/uint32(timeN)) / 1000000 } d["avg_processing_time"] = avgTime From ce614ab8bf8886f177359007459b4b840ab51b83 Mon Sep 17 00:00:00 2001 From: Simon Zolin Date: Tue, 10 Sep 2019 18:04:43 +0300 Subject: [PATCH 4/5] - stats: fix incorrect loading of counters from file --- stats/stats_unit.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/stats/stats_unit.go b/stats/stats_unit.go index e4eba676..5ac574a0 100644 --- a/stats/stats_unit.go +++ b/stats/stats_unit.go @@ -291,9 +291,15 @@ func serialize(u *unit) *unitDB { func deserialize(u *unit, udb *unitDB) { u.nTotal = udb.NTotal - for _, it := range udb.NResult { - u.nResult = append(u.nResult, int(it)) + + n := len(udb.NResult) + if n < len(u.nResult) { + n = len(u.nResult) // n = min(len(udb.NResult), len(u.nResult)) } + for i := 1; i <= n; i++ { + u.nResult[i] = udb.NResult[i] + } + u.domains = convertArrayToMap(udb.Domains) u.blockedDomains = convertArrayToMap(udb.BlockedDomains) u.clients = convertArrayToMap(udb.Clients) From f9091472d790e5e340d0890906f51ef82720e7da Mon Sep 17 00:00:00 2001 From: Simon Zolin Date: Thu, 12 Sep 2019 15:00:41 +0300 Subject: [PATCH 5/5] - openapi: fix --- openapi/openapi.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/openapi/openapi.yaml b/openapi/openapi.yaml index b3b9e42c..f7f56379 100644 --- a/openapi/openapi.yaml +++ b/openapi/openapi.yaml @@ -246,6 +246,7 @@ paths: 200: schema: $ref: "#/definitions/StatsConfig" + description: OK /stats_config: post: