From 4a5cc7c640430ab75e0cf9d1fad5a9491e74f378 Mon Sep 17 00:00:00 2001 From: hardy Date: Thu, 9 Jan 2025 10:15:26 +0800 Subject: [PATCH 1/4] feat: support symlink file detect --- lib/reader/harvester/harvester.go | 22 ++++++------- lib/util/file.go | 51 ++++++++++++++++++++++++++++++- plugin/logs/file_detect.go | 14 +++++++++ 3 files changed, 74 insertions(+), 13 deletions(-) diff --git a/lib/reader/harvester/harvester.go b/lib/reader/harvester/harvester.go index 0820925..e007d14 100644 --- a/lib/reader/harvester/harvester.go +++ b/lib/reader/harvester/harvester.go @@ -8,7 +8,6 @@ import ( "fmt" "io" "os" - "strings" "infini.sh/agent/lib/reader" "infini.sh/agent/lib/reader/linenumber" @@ -30,7 +29,7 @@ type Harvester struct { func NewHarvester(path string, offset int64) (*Harvester, error) { f, err := readOpen(path) - if err != nil { + if f == nil || err != nil { return nil, err } _, err = f.Seek(offset, io.SeekStart) @@ -48,6 +47,9 @@ func NewHarvester(path string, offset int64) (*Harvester, error) { } h.encodingFactory = encodingFactory h.encoding, err = h.encodingFactory(f) + if err != nil { + return nil, err + } return h, nil } @@ -60,6 +62,9 @@ func readOpen(path string) (*os.File, error) { func (h *Harvester) NewJsonFileReader(pattern string, showLineNumber bool) (reader.Reader, error) { var r reader.Reader var err error + if h.file == nil { + return nil, fmt.Errorf("file is nil") + } encReaderMaxBytes := h.config.MaxBytes * 4 r, err = readfile.NewEncodeReader(h.file, readfile.Config{ @@ -97,6 +102,9 @@ func (h *Harvester) NewLogFileReader(pattern string, showLineNumber bool) (reade var r reader.Reader var err error + if h.file == nil { + return nil, fmt.Errorf("file is nil") + } encReaderMaxBytes := h.config.MaxBytes * 4 r, err = readfile.NewEncodeReader(h.file, readfile.Config{ Codec: h.encoding, @@ -125,16 +133,6 @@ func (h *Harvester) NewLogFileReader(pattern string, showLineNumber bool) (reade return h.reader, nil } -// NewPlainTextRead -// 返回一行内容,即使一条日志包含多行(如错误堆栈),也只返回一行。 -func (h *Harvester) NewPlainTextRead(showLineNumber bool) (reader.Reader, error) { - if strings.HasSuffix(h.file.Name(), ".json") { - return h.NewJsonFileReader("", showLineNumber) - } else { - return h.NewLogFileReader("", showLineNumber) - } -} - func (h *Harvester) Close() error { err := h.reader.Close() if err != nil { diff --git a/lib/util/file.go b/lib/util/file.go index 7dc8144..c0cc15b 100644 --- a/lib/util/file.go +++ b/lib/util/file.go @@ -1,3 +1,38 @@ +// CountFileRows counts the number of rows in the specified file. +// It takes a file path as an argument and returns the row count and an error if any. +// If the file cannot be opened, it returns an error. +// +// Parameters: +// - filePath: The path to the file to be read. +// +// Returns: +// - int64: The number of rows in the file. +// - error: An error if the file cannot be opened or read. +// +// Example usage: +// count, err := CountFileRows("/path/to/file") +// if err != nil { +// log.Fatal(err) +// } +// fmt.Println("Number of rows:", count) + +// ResolveSymlink resolves the target file path of a symbolic link. +// It takes a symbolic link path as an argument and returns the absolute path of the target file and an error if any. +// If the symbolic link cannot be resolved, it returns an error. +// +// Parameters: +// - link: The path to the symbolic link. +// +// Returns: +// - string: The absolute path of the target file. +// - error: An error if the symbolic link cannot be resolved. +// +// Example usage: +// realPath, err := ResolveSymlink("/path/to/symlink") +// if err != nil { +// log.Fatal(err) +// } +// fmt.Println("Resolved path:", realPath) /* Copyright © INFINI Ltd. All rights reserved. * Web: https://infinilabs.com * Email: hello#infini.ltd */ @@ -7,9 +42,10 @@ package util import ( "bufio" "os" + "path/filepath" ) -func CountFileRows(filePath string) (int64, error){ +func CountFileRows(filePath string) (int64, error) { file, err := os.Open(filePath) if err != nil { return 0, err @@ -23,3 +59,16 @@ func CountFileRows(filePath string) (int64, error){ } return count, nil } + +// ResolveSymlink Parse the target file path of the soft link +func ResolveSymlink(link string) (string, error) { + realPath, err := filepath.EvalSymlinks(link) + if err != nil { + return "", err + } + absPath, err := filepath.Abs(realPath) + if err != nil { + return "", err + } + return absPath, nil +} diff --git a/plugin/logs/file_detect.go b/plugin/logs/file_detect.go index 413e5ef..e9efe5d 100644 --- a/plugin/logs/file_detect.go +++ b/plugin/logs/file_detect.go @@ -10,6 +10,7 @@ import ( "path/filepath" log "github.com/cihub/seelog" + "infini.sh/agent/lib/util" ) type Operation uint8 @@ -79,6 +80,19 @@ func (w *FileDetector) Detect(ctx context.Context) { } func (w *FileDetector) judgeEvent(ctx context.Context, path string, info os.FileInfo, pattern *Pattern) { + if info.Mode()&os.ModeSymlink != 0 { + realPath, err := util.ResolveSymlink(path) + if err != nil { + log.Error(err) + return + } + info, err = os.Lstat(realPath) + if err != nil { + log.Error(err) + return + } + path = realPath + } preState, err := GetFileState(path) isSameFile := w.IsSameFile(preState, info, path) if err != nil || preState == (FileState{}) || !isSameFile { From fece48956680a9655631b4d71a532717b7ea0417 Mon Sep 17 00:00:00 2001 From: hardy Date: Thu, 9 Jan 2025 10:27:12 +0800 Subject: [PATCH 2/4] fix: add point nil check --- lib/reader/harvester/harvester.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/reader/harvester/harvester.go b/lib/reader/harvester/harvester.go index e007d14..c2a373a 100644 --- a/lib/reader/harvester/harvester.go +++ b/lib/reader/harvester/harvester.go @@ -62,7 +62,7 @@ func readOpen(path string) (*os.File, error) { func (h *Harvester) NewJsonFileReader(pattern string, showLineNumber bool) (reader.Reader, error) { var r reader.Reader var err error - if h.file == nil { + if h == nil || h.file == nil { return nil, fmt.Errorf("file is nil") } @@ -102,7 +102,7 @@ func (h *Harvester) NewLogFileReader(pattern string, showLineNumber bool) (reade var r reader.Reader var err error - if h.file == nil { + if h == nil || h.file == nil { return nil, fmt.Errorf("file is nil") } encReaderMaxBytes := h.config.MaxBytes * 4 From 3631bd8d8f385973647fbb9e9b62f9922e63b958 Mon Sep 17 00:00:00 2001 From: hardy Date: Thu, 9 Jan 2025 10:31:31 +0800 Subject: [PATCH 3/4] fix: remove no use doc --- lib/util/file.go | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/lib/util/file.go b/lib/util/file.go index c0cc15b..4208671 100644 --- a/lib/util/file.go +++ b/lib/util/file.go @@ -1,38 +1,3 @@ -// CountFileRows counts the number of rows in the specified file. -// It takes a file path as an argument and returns the row count and an error if any. -// If the file cannot be opened, it returns an error. -// -// Parameters: -// - filePath: The path to the file to be read. -// -// Returns: -// - int64: The number of rows in the file. -// - error: An error if the file cannot be opened or read. -// -// Example usage: -// count, err := CountFileRows("/path/to/file") -// if err != nil { -// log.Fatal(err) -// } -// fmt.Println("Number of rows:", count) - -// ResolveSymlink resolves the target file path of a symbolic link. -// It takes a symbolic link path as an argument and returns the absolute path of the target file and an error if any. -// If the symbolic link cannot be resolved, it returns an error. -// -// Parameters: -// - link: The path to the symbolic link. -// -// Returns: -// - string: The absolute path of the target file. -// - error: An error if the symbolic link cannot be resolved. -// -// Example usage: -// realPath, err := ResolveSymlink("/path/to/symlink") -// if err != nil { -// log.Fatal(err) -// } -// fmt.Println("Resolved path:", realPath) /* Copyright © INFINI Ltd. All rights reserved. * Web: https://infinilabs.com * Email: hello#infini.ltd */ From 15d2ac115178465b9dd8cc6e736f93e44efdd70c Mon Sep 17 00:00:00 2001 From: hardy Date: Fri, 10 Jan 2025 08:43:36 +0800 Subject: [PATCH 4/4] fix: use setting error --- lib/reader/harvester/harvester.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/reader/harvester/harvester.go b/lib/reader/harvester/harvester.go index c2a373a..29034b0 100644 --- a/lib/reader/harvester/harvester.go +++ b/lib/reader/harvester/harvester.go @@ -15,6 +15,7 @@ import ( "infini.sh/agent/lib/reader/readfile" "infini.sh/agent/lib/reader/readfile/encoding" "infini.sh/agent/lib/reader/readjson" + "infini.sh/framework/core/errors" ) type Harvester struct { @@ -30,7 +31,7 @@ type Harvester struct { func NewHarvester(path string, offset int64) (*Harvester, error) { f, err := readOpen(path) if f == nil || err != nil { - return nil, err + return nil, errors.Errorf("failed to open file(%s),%v", path, err) } _, err = f.Seek(offset, io.SeekStart) if err != nil {