add log position tracking

This commit is contained in:
Fran Jurmanović
2025-06-03 20:57:09 +02:00
parent d57013bb50
commit f218a6b7cd
4 changed files with 95 additions and 6 deletions

View File

@@ -11,6 +11,7 @@ type LogTailer struct {
handleLine func(string)
stopChan chan struct{}
isRunning bool
tracker *PositionTracker
}
func NewLogTailer(filePath string, handleLine func(string)) *LogTailer {
@@ -18,6 +19,7 @@ func NewLogTailer(filePath string, handleLine func(string)) *LogTailer {
filePath: filePath,
handleLine: handleLine,
stopChan: make(chan struct{}),
tracker: NewPositionTracker(filePath),
}
}
@@ -28,7 +30,13 @@ func (t *LogTailer) Start() {
t.isRunning = true
go func() {
var lastSize int64 = 0
// Load last position from tracker
pos, err := t.tracker.LoadPosition()
if err != nil {
pos = &LogPosition{} // Start from beginning if error
}
lastSize := pos.LastPosition
for {
select {
case <-t.stopChan:
@@ -56,8 +64,15 @@ func (t *LogTailer) Start() {
scanner := bufio.NewScanner(file)
for scanner.Scan() {
t.handleLine(scanner.Text())
line := scanner.Text()
t.handleLine(line)
lastSize, _ = file.Seek(0, 1) // Get current position
// Save position periodically
t.tracker.SavePosition(&LogPosition{
LastPosition: lastSize,
LastRead: line,
})
}
file.Close()

View File

@@ -0,0 +1,54 @@
package tracking
import (
"encoding/json"
"os"
"path/filepath"
)
type LogPosition struct {
LastPosition int64 `json:"last_position"`
LastRead string `json:"last_read"`
}
type PositionTracker struct {
positionFile string
}
func NewPositionTracker(logPath string) *PositionTracker {
// Create position file in same directory as log file
dir := filepath.Dir(logPath)
base := filepath.Base(logPath)
positionFile := filepath.Join(dir, "."+base+".position")
return &PositionTracker{
positionFile: positionFile,
}
}
func (t *PositionTracker) LoadPosition() (*LogPosition, error) {
data, err := os.ReadFile(t.positionFile)
if err != nil {
if os.IsNotExist(err) {
// Return empty position if file doesn't exist
return &LogPosition{}, nil
}
return nil, err
}
var pos LogPosition
if err := json.Unmarshal(data, &pos); err != nil {
return nil, err
}
return &pos, nil
}
func (t *PositionTracker) SavePosition(pos *LogPosition) error {
data, err := json.Marshal(pos)
if err != nil {
return err
}
return os.WriteFile(t.positionFile, data, 0644)
}