From 2ae838cf7b241ed01503c96464c162d64bd22516 Mon Sep 17 00:00:00 2001 From: Denis Mishankov Date: Sun, 24 Nov 2024 18:37:05 +0300 Subject: [PATCH] tail -f -n X functionality for local files (#68) --- go.mod | 1 + go.sum | 4 ++++ server/sources.go | 38 ++++++++++++++++++++++++++++++++++++++ utils/generate_logs.js | 2 +- 4 files changed, 44 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 4fe8f9e..028a7ea 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require github.com/go-chi/chi/v5 v5.1.0 require ( github.com/gorilla/websocket v1.5.3 + github.com/icza/backscanner v0.0.0-20240328210400-b40c3a86dec5 github.com/mishankov/go-utlz v0.0.3 github.com/nxadm/tail v1.4.11 golang.org/x/crypto v0.29.0 diff --git a/go.sum b/go.sum index ff4e893..da56fac 100644 --- a/go.sum +++ b/go.sum @@ -6,6 +6,10 @@ github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/icza/backscanner v0.0.0-20240328210400-b40c3a86dec5 h1:FcxwOojw6pUiPpsf7Q6Fw/pI+7cR6FlapLBEGV/902A= +github.com/icza/backscanner v0.0.0-20240328210400-b40c3a86dec5/go.mod h1:GYeBD1CF7AqnKZK+UCytLcY3G+UKo0ByXX/3xfdNyqQ= +github.com/icza/mighty v0.0.0-20180919140131-cfd07d671de6 h1:8UsGZ2rr2ksmEru6lToqnXgA8Mz1DP11X4zSJ159C3k= +github.com/icza/mighty v0.0.0-20180919140131-cfd07d671de6/go.mod h1:xQig96I1VNBDIWGCdTt54nHt6EeI639SmHycLYL7FkA= github.com/mishankov/go-utlz v0.0.3 h1:iSrGlCeJ8La5M9oFuELQ1AIA6W/nWxilfA7bjiP2hoE= github.com/mishankov/go-utlz v0.0.3/go.mod h1:ioIgxxn/MMg+7AWli68mApcJXXpaDQ6790Hu0tQFV6E= github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= diff --git a/server/sources.go b/server/sources.go index 2508ed9..1d9183e 100644 --- a/server/sources.go +++ b/server/sources.go @@ -7,8 +7,10 @@ import ( "iter" "os" "os/exec" + "slices" "strconv" + "github.com/icza/backscanner" "github.com/nxadm/tail" "golang.org/x/crypto/ssh" ) @@ -58,6 +60,39 @@ type LocalFile struct { } func (lf LocalFile) Tail() (iter.Seq[string], error) { + initialLines := []string{} + + file, err := os.Open(lf.filePath) + if err != nil { + logger.Error("Error opening local file:", err) + return nil, err + } + + fileStatus, err := file.Stat() + if err != nil { + logger.Error("Error getting stat of local file:", err) + return nil, err + } + defer file.Close() + + scanner := backscanner.New(file, int(fileStatus.Size())) + for { + line, _, err := scanner.LineBytes() + if err != nil { + if err == io.EOF { + break + } + } + + initialLines = append(initialLines, string(line)) + + if len(initialLines) >= lf.initialAmount { + break + } + } + + slices.Reverse(initialLines) + t, err := tail.TailFile(lf.filePath, tail.Config{Poll: true, Follow: true, ReOpen: true, Location: &tail.SeekInfo{Offset: 0, Whence: io.SeekEnd}}) if err != nil { logger.Error("Error setuping tail file:", err) @@ -65,6 +100,9 @@ func (lf LocalFile) Tail() (iter.Seq[string], error) { } return func(yield func(string) bool) { + for _, line := range initialLines { + yield(line) + } for line := range t.Lines { yield(line.Text) } diff --git a/utils/generate_logs.js b/utils/generate_logs.js index ada85ae..7132fc4 100644 --- a/utils/generate_logs.js +++ b/utils/generate_logs.js @@ -8,7 +8,7 @@ async function run() { console.log(logLine); - fs.writeFile("dist/myfile.log", logLine, { flag: "a+" }, (err) => {}); + fs.writeFile("myfile.log", logLine, { flag: "a+" }, (err) => {}); } }