Merge in DNS/adguard-home from 3890-fix-stats to master
Updates #3890.
Squashed commit of the following:
commit a77a6204bc8a58f62a4fac70efdcae4267a64810
Merge: 834493a2 90e65b66
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Mon Dec 6 17:22:16 2021 +0300
Merge branch 'master' into 3890-fix-stats
commit 834493a22ae79199efcc44e0715e2ac6f6272963
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Mon Dec 6 17:09:30 2021 +0300
querylog: load once
commit b8000e7ba7a998fcd4553230ec5e5f9c90106e31
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Mon Dec 6 16:54:41 2021 +0300
querylog: fix docs
commit 7db99ccfa19b58100950c11d67b23bca7af3e5cb
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Mon Dec 6 16:51:31 2021 +0300
querylog: imp docs
commit 2a84650bd7ac5195730a7ab47b9562a83f721499
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Mon Dec 6 15:48:09 2021 +0300
querylog: imp anonyization
commit 0f63feb1ff5f006fc528c3b681ef3b9d2199581e
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Mon Dec 6 14:44:37 2021 +0300
all: imp code & docs
commit c4ccdcbb7248897edd178fd5cb77127e39ada73d
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Mon Dec 6 14:24:30 2021 +0300
all: log changes
commit 60bb777a5aff36bba129a078fa11ae566298178a
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Mon Dec 6 14:08:41 2021 +0300
all: use atomic value
commit c45886bd20eee2212b42686ff369830d8c08fe36
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date: Tue Nov 30 18:50:02 2021 +0300
all: anonymize separately
139 lines
3.4 KiB
Go
139 lines
3.4 KiB
Go
package querylog
|
|
|
|
import (
|
|
"net"
|
|
"net/http"
|
|
"path/filepath"
|
|
"time"
|
|
|
|
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
|
|
"github.com/AdguardTeam/AdGuardHome/internal/filtering"
|
|
"github.com/AdguardTeam/golibs/errors"
|
|
"github.com/AdguardTeam/golibs/log"
|
|
"github.com/AdguardTeam/golibs/timeutil"
|
|
"github.com/miekg/dns"
|
|
)
|
|
|
|
// QueryLog - main interface
|
|
type QueryLog interface {
|
|
Start()
|
|
|
|
// Close query log object
|
|
Close()
|
|
|
|
// Add a log entry
|
|
Add(params AddParams)
|
|
|
|
// WriteDiskConfig - write configuration
|
|
WriteDiskConfig(c *Config)
|
|
}
|
|
|
|
// Config - configuration object
|
|
type Config struct {
|
|
// ConfigModified is called when the configuration is changed, for
|
|
// example by HTTP requests.
|
|
ConfigModified func()
|
|
|
|
// HTTPRegister registers an HTTP handler.
|
|
HTTPRegister func(string, string, func(http.ResponseWriter, *http.Request))
|
|
|
|
// FindClient returns client information by their IDs.
|
|
FindClient func(ids []string) (c *Client, err error)
|
|
|
|
// BaseDir is the base directory for log files.
|
|
BaseDir string
|
|
|
|
// RotationIvl is the interval for log rotation. After that period, the
|
|
// old log file will be renamed, NOT deleted, so the actual log
|
|
// retention time is twice the interval. The value must be one of:
|
|
//
|
|
// 6 * time.Hour
|
|
// 1 * timeutil.Day
|
|
// 7 * timeutil.Day
|
|
// 30 * timeutil.Day
|
|
// 90 * timeutil.Day
|
|
//
|
|
RotationIvl time.Duration
|
|
|
|
// MemSize is the number of entries kept in a memory buffer before they
|
|
// are flushed to disk.
|
|
MemSize uint32
|
|
|
|
// Enabled tells if the query log is enabled.
|
|
Enabled bool
|
|
|
|
// FileEnabled tells if the query log writes logs to files.
|
|
FileEnabled bool
|
|
|
|
// AnonymizeClientIP tells if the query log should anonymize clients' IP
|
|
// addresses.
|
|
AnonymizeClientIP bool
|
|
|
|
// Anonymizer proccesses the IP addresses to anonymize those if needed.
|
|
Anonymizer *aghnet.IPMut
|
|
}
|
|
|
|
// AddParams - parameters for Add()
|
|
type AddParams struct {
|
|
Question *dns.Msg
|
|
Answer *dns.Msg // The response we sent to the client (optional)
|
|
OrigAnswer *dns.Msg // The response from an upstream server (optional)
|
|
Result *filtering.Result // Filtering result (optional)
|
|
Elapsed time.Duration // Time spent for processing the request
|
|
ClientID string
|
|
ClientIP net.IP
|
|
Upstream string // Upstream server URL
|
|
ClientProto ClientProto
|
|
}
|
|
|
|
// validate returns an error if the parameters aren't valid.
|
|
func (p *AddParams) validate() (err error) {
|
|
switch {
|
|
case p.Question == nil:
|
|
return errors.Error("question is nil")
|
|
case len(p.Question.Question) != 1:
|
|
return errors.Error("more than one question")
|
|
case len(p.Question.Question[0].Name) == 0:
|
|
return errors.Error("no host in question")
|
|
case p.ClientIP == nil:
|
|
return errors.Error("no client ip")
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// New creates a new instance of the query log.
|
|
func New(conf Config) (ql QueryLog) {
|
|
return newQueryLog(conf)
|
|
}
|
|
|
|
// newQueryLog crates a new queryLog.
|
|
func newQueryLog(conf Config) (l *queryLog) {
|
|
findClient := conf.FindClient
|
|
if findClient == nil {
|
|
findClient = func(_ []string) (_ *Client, _ error) {
|
|
return nil, nil
|
|
}
|
|
}
|
|
|
|
l = &queryLog{
|
|
findClient: findClient,
|
|
|
|
logFile: filepath.Join(conf.BaseDir, queryLogFileName),
|
|
anonymizer: conf.Anonymizer,
|
|
}
|
|
|
|
l.conf = &Config{}
|
|
*l.conf = conf
|
|
|
|
if !checkInterval(conf.RotationIvl) {
|
|
log.Info(
|
|
"querylog: warning: unsupported rotation interval %s, setting to 1 day",
|
|
conf.RotationIvl,
|
|
)
|
|
l.conf.RotationIvl = timeutil.Day
|
|
}
|
|
|
|
return l
|
|
}
|