Skip to content

Commit ded6c6d

Browse files
committed
feat: support real-time reading of gzip log files
1 parent fdb2e62 commit ded6c6d

File tree

2 files changed

+74
-21
lines changed

2 files changed

+74
-21
lines changed

lib/util/file.go

+33
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ package util
66

77
import (
88
"bufio"
9+
"compress/gzip"
10+
"fmt"
11+
"io"
912
"os"
1013
"path/filepath"
1114
)
@@ -37,3 +40,33 @@ func ResolveSymlink(link string) (string, error) {
3740
}
3841
return absPath, nil
3942
}
43+
44+
// UnpackGzipFile extracts a .gz file and writes the output to a regular file.
45+
func UnpackGzipFile(gzFile, outputFile string) error {
46+
f, err := os.Open(gzFile)
47+
if err != nil {
48+
return fmt.Errorf("failed to open .gz file %s: %w", gzFile, err)
49+
}
50+
defer f.Close()
51+
52+
// Create a gzip reader
53+
gzReader, err := gzip.NewReader(f)
54+
if err != nil {
55+
return fmt.Errorf("failed to create gzip reader with file %s: %w", gzFile, err)
56+
}
57+
defer gzReader.Close()
58+
59+
// Create the output file
60+
outFile, err := os.Create(outputFile)
61+
if err != nil {
62+
return fmt.Errorf("failed to create output file %s: %w", outputFile, err)
63+
}
64+
defer outFile.Close()
65+
66+
// Copy decompressed content to output file
67+
_, err = io.Copy(outFile, gzReader)
68+
if err != nil {
69+
return fmt.Errorf("failed to write to output file %s: %w", outputFile, err)
70+
}
71+
return nil
72+
}

plugin/api/log.go

+41-21
Original file line numberDiff line numberDiff line change
@@ -37,28 +37,26 @@ func (handler *AgentAPI) getElasticLogFiles(w http.ResponseWriter, req *http.Req
3737
}
3838
var files []util.MapStr
3939
for _, info := range fileInfos {
40-
if strings.HasSuffix(info.Name(), ".log") || strings.HasSuffix(info.Name(), ".json") {
41-
if info.IsDir() {
42-
continue
43-
}
44-
fInfo, err := info.Info()
45-
if err != nil {
46-
log.Error(err)
47-
continue
48-
}
49-
filePath := path.Join(reqBody.LogsPath, info.Name())
50-
totalRows, err := util2.CountFileRows(filePath)
51-
if err != nil {
52-
log.Error(err)
53-
continue
54-
}
55-
files = append(files, util.MapStr{
56-
"name": fInfo.Name(),
57-
"size_in_bytes": fInfo.Size(),
58-
"modify_time": fInfo.ModTime(),
59-
"total_rows": totalRows,
60-
})
40+
if info.IsDir() {
41+
continue
42+
}
43+
fInfo, err := info.Info()
44+
if err != nil {
45+
log.Error(err)
46+
continue
47+
}
48+
filePath := path.Join(reqBody.LogsPath, info.Name())
49+
totalRows, err := util2.CountFileRows(filePath)
50+
if err != nil {
51+
log.Error(err)
52+
continue
6153
}
54+
files = append(files, util.MapStr{
55+
"name": fInfo.Name(),
56+
"size_in_bytes": fInfo.Size(),
57+
"modify_time": fInfo.ModTime(),
58+
"total_rows": totalRows,
59+
})
6260
}
6361

6462
handler.WriteJSON(w, util.MapStr{
@@ -80,6 +78,28 @@ func (handler *AgentAPI) readElasticLogFile(w http.ResponseWriter, req *http.Req
8078
if reqBody.StartLineNumber < 0 {
8179
reqBody.StartLineNumber = 0
8280
}
81+
if strings.HasSuffix(reqBody.FileName, ".gz") {
82+
// read gzip log file, and then unpack it to tmp file
83+
tmpFilePath := filepath.Join(os.TempDir(), "agent", strings.TrimSuffix(reqBody.FileName, ".gz"))
84+
if !util.FileExists(tmpFilePath) {
85+
fileDir := filepath.Dir(tmpFilePath)
86+
if !util.FileExists(fileDir) {
87+
err = os.MkdirAll(fileDir, os.ModePerm)
88+
if err != nil {
89+
log.Error(err)
90+
handler.WriteJSON(w, err.Error(), http.StatusInternalServerError)
91+
return
92+
}
93+
}
94+
err = util2.UnpackGzipFile(logFilePath, tmpFilePath)
95+
if err != nil {
96+
log.Error(err)
97+
handler.WriteJSON(w, err.Error(), http.StatusInternalServerError)
98+
return
99+
}
100+
}
101+
logFilePath = tmpFilePath
102+
}
83103
r, err := linenumber.NewLinePlainTextReader(logFilePath, reqBody.StartLineNumber, io.SeekStart)
84104
if err != nil {
85105
log.Error(err)

0 commit comments

Comments
 (0)