Browse Source

go.d squidlog: improve parser init and parsing (#18368)

Ilya Mashchenko 6 months ago
parent
commit
6fafa32b09

+ 34 - 15
src/go/plugin/go.d/modules/squidlog/init.go

@@ -3,7 +3,6 @@
 package squidlog
 
 import (
-	"bytes"
 	"fmt"
 	"strings"
 
@@ -26,28 +25,48 @@ func (s *SquidLog) createLogReader() error {
 
 func (s *SquidLog) createParser() error {
 	s.Debug("starting parser creating")
-	lastLine, err := logs.ReadLastLine(s.file.CurrentFilename(), 0)
-	if err != nil {
-		return fmt.Errorf("read last line: %v", err)
-	}
 
-	lastLine = bytes.TrimRight(lastLine, "\n")
-	s.Debugf("last line: '%s'", string(lastLine))
+	const readLastLinesNum = 100
 
-	s.parser, err = logs.NewParser(s.ParserConfig, s.file)
+	lines, err := logs.ReadLastLines(s.file.CurrentFilename(), readLastLinesNum)
 	if err != nil {
-		return fmt.Errorf("create parser: %v", err)
+		return fmt.Errorf("failed to read last lines: %v", err)
 	}
-	s.Debugf("created parser: %s", s.parser.Info())
 
-	err = s.parser.Parse(lastLine, s.line)
-	if err != nil {
-		return fmt.Errorf("parse last line: %v (%s)", err, string(lastLine))
+	var found bool
+	for _, line := range lines {
+		if line = strings.TrimSpace(line); line == "" {
+			continue
+		}
+
+		s.Debugf("last line: '%s'", line)
+
+		s.parser, err = logs.NewParser(s.ParserConfig, s.file)
+		if err != nil {
+			s.Debugf("failed to create parser from line: %v", err)
+			continue
+		}
+
+		s.line.reset()
+
+		if err = s.parser.Parse([]byte(line), s.line); err != nil {
+			s.Debugf("failed to parse line: %v", err)
+			continue
+		}
+
+		if err = s.line.verify(); err != nil {
+			s.Debugf("failed to verify line: %v", err)
+			continue
+		}
+
+		found = true
+		break
 	}
 
-	if err = s.line.verify(); err != nil {
-		return fmt.Errorf("verify last line: %v (%s)", err, string(lastLine))
+	if !found {
+		return fmt.Errorf("failed to create log parser (file '%s')", s.file.CurrentFilename())
 	}
+
 	return nil
 }
 

+ 8 - 2
src/go/plugin/go.d/modules/squidlog/logline.go

@@ -245,10 +245,16 @@ func (l *logLine) assignMimeType(mime string) error {
 	}
 	// format: type/subtype, type/subtype;parameter=value
 	i := strings.IndexByte(mime, '/')
-	if i <= 0 || !isMimeTypeValid(mime[:i]) {
+	if i <= 0 {
 		return fmt.Errorf("assign '%s': %w", mime, errBadMimeType)
 	}
+
+	if !isMimeTypeValid(mime[:i]) {
+		return nil
+	}
+
 	l.mimeType = mime[:i] // drop subtype
+
 	return nil
 }
 
@@ -345,7 +351,7 @@ func isRespTimeValid(time int) bool {
 // isCacheCodeValid does not guarantee cache result code is valid, but it is very likely.
 func isCacheCodeValid(code string) bool {
 	// https://wiki.squid-cache.org/SquidFaq/SquidLogs#Squid_result_codes
-	if code == "NONE" {
+	if code == "NONE" || code == "NONE_NONE" {
 		return true
 	}
 	return len(code) > 5 && (code[:4] == "TCP_" || code[:4] == "UDP_")

+ 4 - 2
src/go/plugin/go.d/modules/squidlog/logline_test.go

@@ -60,6 +60,7 @@ func TestLogLine_Assign(t *testing.T) {
 				{input: "UDP_MISS_NOFETCH", wantLine: logLine{cacheCode: "UDP_MISS_NOFETCH"}},
 				{input: "UDP_INVALID", wantLine: logLine{cacheCode: "UDP_INVALID"}},
 				{input: "NONE", wantLine: logLine{cacheCode: "NONE"}},
+				{input: "NONE_NONE", wantLine: logLine{cacheCode: "NONE_NONE"}},
 				{input: emptyStr, wantLine: emptyLogLine},
 				{input: hyphen, wantLine: emptyLogLine, wantErr: errBadCacheCode},
 				{input: "TCP", wantLine: emptyLogLine, wantErr: errBadCacheCode},
@@ -173,8 +174,8 @@ func TestLogLine_Assign(t *testing.T) {
 				{input: "video/3gpp", wantLine: logLine{mimeType: "video"}},
 				{input: emptyStr, wantLine: emptyLogLine},
 				{input: hyphen, wantLine: emptyLogLine},
-				{input: "example/example", wantLine: emptyLogLine, wantErr: errBadMimeType},
-				{input: "unknown/example", wantLine: emptyLogLine, wantErr: errBadMimeType},
+				{input: "example/example", wantLine: emptyLogLine},
+				{input: "unknown/example", wantLine: emptyLogLine},
 				{input: "audio", wantLine: emptyLogLine, wantErr: errBadMimeType},
 				{input: "/", wantLine: emptyLogLine, wantErr: errBadMimeType},
 			},
@@ -274,6 +275,7 @@ func TestLogLine_verify(t *testing.T) {
 				{input: "UDP_MISS_NOFETCH"},
 				{input: "UDP_INVALID"},
 				{input: "NONE"},
+				{input: "NONE_NONE"},
 				{input: emptyStr},
 				{input: "TCP", wantErr: errBadCacheCode},
 				{input: "UDP", wantErr: errBadCacheCode},