Pull request: querylog imp code
Merge in DNS/adguard-home from querylog-imp-code to master Squashed commit of the following: commit a58ad36508a2355b686d314dec51ac0b5e357281 Merge: df5494f2c941eb1dd7Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Wed May 24 15:26:55 2023 +0300 Merge remote-tracking branch 'origin/master' into querylog-imp-code commit df5494f2c337736690a3c2a547c2d71858d0378f Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Wed May 24 15:24:43 2023 +0300 querylog: imp code commit 8c3c2b76dd5858e7b107f222c112e9cde2477fb3 Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Wed May 24 12:14:15 2023 +0300 all: lint script commit be04a4decfaf20a1649d32ecaab3c1c6bb205ffd Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Wed May 24 12:03:12 2023 +0300 querylog: imp code commit fe7beacff3a5cfcf2332c4998b9c65820284eaf7 Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Wed May 24 11:57:33 2023 +0300 querylog: imp docs commit 2ae239c57d12524fbc092f582842af2ad726c1d0 Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Wed May 24 11:46:54 2023 +0300 querylog: imp code commit 417216cefbf154fa870f8f43468f35e0e345971f Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Wed May 24 11:25:44 2023 +0300 querylog: imp code commit 514b6ee99113844a4e0dad30dc53703e3220c289 Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Wed May 24 11:14:13 2023 +0300 querylog: imp docs commit 321351a3abb524208daacd5a3a7fbf5f07ab259d Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Mon May 22 16:38:31 2023 +0300 querylog: imp code commit ee91de5c43210b5bc213f933d411adb894d2e586 Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Mon May 22 16:01:32 2023 +0300 querylog: imp code commit 862ff12177fb769d5cb2ec250eaee538dc91d70a Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Mon May 22 15:07:24 2023 +0300 querylog: imp code commit cc62c1c4ae8b813d03ccf51b596ba1ebf44d9a1f Merge: 37ace34e924b41100cAuthor: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Mon May 22 13:09:10 2023 +0300 Merge remote-tracking branch 'origin/master' into querylog-imp-code commit 37ace34e91e5189bef6e774db960f40cdaa18270 Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Mon May 22 11:23:08 2023 +0300 querylog: imp code commit 8417815a6349f10b5dbad410ce28aab98bc479fa Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Mon May 22 11:08:29 2023 +0300 querylog: imp docs commit 4e5cde74d25713f78675aa3e18083b4fb5e619f3 Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Fri May 19 16:41:34 2023 +0300 querylog: imp code commit 3494eab7006240f652a0217d305ac916bd6c3c83 Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Fri May 19 16:13:08 2023 +0300 all: lint script commit 704534ce6278e7d9b1bef30a3acc4e59f25693bc Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Fri May 19 16:12:04 2023 +0300 querylog: imp code commit 48510102a2fa5187f78067d2b9157dac62f8bb56 Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Fri May 19 15:52:57 2023 +0300 querylog: imp code commit 89c273aea0e6758eb749a2d3bbaf1bc385a57797 Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Fri May 19 15:40:50 2023 +0300 querylog: imp code commit 0057fe64553ad38de0fda10efb9d3512c9a00e45 Author: Dimitry Kolyshev <dkolyshev@adguard.com> Date: Fri May 19 13:54:46 2023 +0300 querylog: imp code ... and 1 more commit
This commit is contained in:
@@ -9,36 +9,36 @@ import (
|
||||
"github.com/AdguardTeam/golibs/log"
|
||||
)
|
||||
|
||||
// QLogReader allows reading from multiple query log files in the reverse order.
|
||||
// qLogReader allows reading from multiple query log files in the reverse
|
||||
// order.
|
||||
//
|
||||
// Please note that this is a stateful object.
|
||||
// Internally, it contains a pointer to a particular query log file, and
|
||||
// to a specific position in this file, and it reads lines in reverse order
|
||||
// starting from that position.
|
||||
type QLogReader struct {
|
||||
// qFiles - array with the query log files
|
||||
// The order is - from oldest to newest
|
||||
qFiles []*QLogFile
|
||||
// Please note that this is a stateful object. Internally, it contains a
|
||||
// pointer to a particular query log file, and to a specific position in this
|
||||
// file, and it reads lines in reverse order starting from that position.
|
||||
type qLogReader struct {
|
||||
// qFiles is an array with the query log files. The order is from oldest
|
||||
// to newest.
|
||||
qFiles []*qLogFile
|
||||
|
||||
currentFile int // Index of the current file
|
||||
// currentFile is the index of the current file.
|
||||
currentFile int
|
||||
}
|
||||
|
||||
// NewQLogReader initializes a QLogReader instance
|
||||
// with the specified files
|
||||
func NewQLogReader(files []string) (*QLogReader, error) {
|
||||
qFiles := make([]*QLogFile, 0)
|
||||
// newQLogReader initializes a qLogReader instance with the specified files.
|
||||
func newQLogReader(files []string) (*qLogReader, error) {
|
||||
qFiles := make([]*qLogFile, 0)
|
||||
|
||||
for _, f := range files {
|
||||
q, err := NewQLogFile(f)
|
||||
q, err := newQLogFile(f)
|
||||
if err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Close what we've already opened.
|
||||
cerr := closeQFiles(qFiles)
|
||||
if cerr != nil {
|
||||
log.Debug("querylog: closing files: %s", cerr)
|
||||
cErr := closeQFiles(qFiles)
|
||||
if cErr != nil {
|
||||
log.Debug("querylog: closing files: %s", cErr)
|
||||
}
|
||||
|
||||
return nil, err
|
||||
@@ -47,31 +47,28 @@ func NewQLogReader(files []string) (*QLogReader, error) {
|
||||
qFiles = append(qFiles, q)
|
||||
}
|
||||
|
||||
return &QLogReader{
|
||||
qFiles: qFiles,
|
||||
currentFile: (len(qFiles) - 1),
|
||||
}, nil
|
||||
return &qLogReader{qFiles: qFiles, currentFile: len(qFiles) - 1}, nil
|
||||
}
|
||||
|
||||
// seekTS performs binary search of a query log record with the specified
|
||||
// timestamp. If the record is found, it sets QLogReader's position to point to
|
||||
// that line, so that the next ReadNext call returned this line.
|
||||
func (r *QLogReader) seekTS(timestamp int64) (err error) {
|
||||
// timestamp. If the record is found, it sets qLogReader's position to point
|
||||
// to that line, so that the next ReadNext call returned this line.
|
||||
func (r *qLogReader) seekTS(timestamp int64) (err error) {
|
||||
for i := len(r.qFiles) - 1; i >= 0; i-- {
|
||||
q := r.qFiles[i]
|
||||
_, _, err = q.seekTS(timestamp)
|
||||
if err != nil {
|
||||
if errors.Is(err, ErrTSTooEarly) {
|
||||
if errors.Is(err, errTSTooEarly) {
|
||||
// Look at the next file, since we've reached the end of this
|
||||
// one. If there is no next file, it's not found.
|
||||
err = ErrTSNotFound
|
||||
err = errTSNotFound
|
||||
|
||||
continue
|
||||
} else if errors.Is(err, ErrTSTooLate) {
|
||||
} else if errors.Is(err, errTSTooLate) {
|
||||
// Just seek to the start then. timestamp is probably between
|
||||
// the end of the previous one and the start of this one.
|
||||
return r.SeekStart()
|
||||
} else if errors.Is(err, ErrTSNotFound) {
|
||||
} else if errors.Is(err, errTSNotFound) {
|
||||
return err
|
||||
} else {
|
||||
return fmt.Errorf("seekts: file at index %d: %w", i, err)
|
||||
@@ -80,7 +77,7 @@ func (r *QLogReader) seekTS(timestamp int64) (err error) {
|
||||
|
||||
// The search is finished, and the searched element has been found.
|
||||
// Update currentFile only, position is already set properly in
|
||||
// QLogFile.
|
||||
// qLogFile.
|
||||
r.currentFile = i
|
||||
|
||||
return nil
|
||||
@@ -93,13 +90,13 @@ func (r *QLogReader) seekTS(timestamp int64) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SeekStart changes the current position to the end of the newest file
|
||||
// Please note that we're reading query log in the reverse order
|
||||
// and that's why log start is actually the end of file
|
||||
// SeekStart changes the current position to the end of the newest file.
|
||||
// Please note that we're reading query log in the reverse order and that's why
|
||||
// the log starts actually at the end of file.
|
||||
//
|
||||
// Returns nil if we were able to change the current position.
|
||||
// Returns error in any other case.
|
||||
func (r *QLogReader) SeekStart() error {
|
||||
// Returns nil if we were able to change the current position. Returns error
|
||||
// in any other cases.
|
||||
func (r *qLogReader) SeekStart() error {
|
||||
if len(r.qFiles) == 0 {
|
||||
return nil
|
||||
}
|
||||
@@ -110,10 +107,12 @@ func (r *QLogReader) SeekStart() error {
|
||||
return err
|
||||
}
|
||||
|
||||
// ReadNext reads the next line (in the reverse order) from the query log files.
|
||||
// and shifts the current position left to the next (actually prev) line (or the next file).
|
||||
// returns io.EOF if there's nothing to read more.
|
||||
func (r *QLogReader) ReadNext() (string, error) {
|
||||
// ReadNext reads the next line (in the reverse order) from the query log
|
||||
// files. Then shifts the current position left to the next (actually prev)
|
||||
// line (or the next file).
|
||||
//
|
||||
// Returns io.EOF if there is nothing more to read.
|
||||
func (r *qLogReader) ReadNext() (string, error) {
|
||||
if len(r.qFiles) == 0 {
|
||||
return "", io.EOF
|
||||
}
|
||||
@@ -122,7 +121,7 @@ func (r *QLogReader) ReadNext() (string, error) {
|
||||
q := r.qFiles[r.currentFile]
|
||||
line, err := q.ReadNext()
|
||||
if err != nil {
|
||||
// Shift to the older file
|
||||
// Shift to the older file.
|
||||
r.currentFile--
|
||||
if r.currentFile < 0 {
|
||||
break
|
||||
@@ -130,10 +129,10 @@ func (r *QLogReader) ReadNext() (string, error) {
|
||||
|
||||
q = r.qFiles[r.currentFile]
|
||||
|
||||
// Set it's position to the start right away
|
||||
// Set its position to the start right away.
|
||||
_, err = q.SeekStart()
|
||||
|
||||
// This is unexpected, return an error right away
|
||||
// This is unexpected, return an error right away.
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -142,17 +141,17 @@ func (r *QLogReader) ReadNext() (string, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Nothing to read anymore
|
||||
// Nothing to read anymore.
|
||||
return "", io.EOF
|
||||
}
|
||||
|
||||
// Close closes the QLogReader
|
||||
func (r *QLogReader) Close() error {
|
||||
// Close closes the qLogReader.
|
||||
func (r *qLogReader) Close() error {
|
||||
return closeQFiles(r.qFiles)
|
||||
}
|
||||
|
||||
// closeQFiles - helper method to close multiple QLogFile instances
|
||||
func closeQFiles(qFiles []*QLogFile) error {
|
||||
// closeQFiles is a helper method to close multiple qLogFile instances.
|
||||
func closeQFiles(qFiles []*qLogFile) error {
|
||||
var errs []error
|
||||
|
||||
for _, q := range qFiles {
|
||||
@@ -163,7 +162,7 @@ func closeQFiles(qFiles []*QLogFile) error {
|
||||
}
|
||||
|
||||
if len(errs) > 0 {
|
||||
return errors.List("error while closing QLogReader", errs...)
|
||||
return errors.List("error while closing qLogReader", errs...)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user