cherry-pick: 4142 stats panic

Merge in DNS/adguard-home from 4142-stats-panic to master

Updates #4142.

Squashed commit of the following:

commit bf168f50ac86bdfdab73bf7285705f09f87b6c72
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Jan 20 17:13:41 2022 +0300

    stats: imp more

commit bb638211da7d0c51959ded2dacb72faea00befb4
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Jan 20 17:09:31 2022 +0300

    stats: imp code quality

commit 27ac52f15e4e0f4112ce7a6b47b03f963463393e
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Jan 20 17:00:09 2022 +0300

    stats: recover panic on init

commit 1ffcebbb9062438170b010e1c7bad3c6cef4cfc1
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Jan 20 14:19:01 2022 +0300

    all: fix some typos
This commit is contained in:
Eugene Burkov 2022-01-20 17:19:09 +03:00 committed by Ainar Garipov
parent 5ebdd1390e
commit 2491426b09
5 changed files with 26 additions and 4 deletions

View file

@ -51,7 +51,7 @@ and this project adheres to
<!--
## [v0.107.3] - 2022-01-19 (APPROX.)
## [v0.107.3] - 2022-02-08 (APPROX.)
-->

View file

@ -24,7 +24,7 @@ func (uc UniqChecker) Add(elems ...comparable) {
}
}
// Merge returns a validator containing data from both v and other.
// Merge returns a checker containing data from both uc and other.
func (uc UniqChecker) Merge(other UniqChecker) (merged UniqChecker) {
merged = make(UniqChecker, len(uc)+len(other))
for elem, num := range uc {

View file

@ -128,7 +128,7 @@ func (req *checkConfReq) validateWeb(uc aghalg.UniqChecker) (err error) {
}
// validateDNS returns error if the DNS part of the initial configuration can't
// be set. autofix is true if the port can be unbound by AdGuard Home
// be set. canAutofix is true if the port can be unbound by AdGuard Home
// automatically.
func (req *checkConfReq) validateDNS(uc aghalg.UniqChecker) (canAutofix bool, err error) {
defer func() { err = errors.Annotate(err, "validating ports: %w") }()

View file

@ -54,7 +54,7 @@ func initDNSServer() (err error) {
}
Context.stats, err = stats.New(statsConf)
if err != nil {
return fmt.Errorf("couldn't initialize statistics module")
return fmt.Errorf("init stats: %w", err)
}
conf := querylog.Config{

View file

@ -67,7 +67,29 @@ type unitDB struct {
TimeAvg uint32 // usec
}
// withRecovered turns the value recovered from panic if any into an error and
// combines it with the one pointed by orig. orig must be non-nil.
func withRecovered(orig *error) {
p := recover()
if p == nil {
return
}
var err error
switch p := p.(type) {
case error:
err = fmt.Errorf("panic: %w", p)
default:
err = fmt.Errorf("panic: recovered value of type %[1]T: %[1]v", p)
}
*orig = errors.WithDeferred(*orig, err)
}
// createObject creates s from conf and properly initializes it.
func createObject(conf Config) (s *statsCtx, err error) {
defer withRecovered(&err)
s = &statsCtx{
mu: &sync.Mutex{},
}