add step list for server creation
This commit is contained in:
@@ -7,11 +7,11 @@ import (
|
||||
)
|
||||
|
||||
type LogTailer struct {
|
||||
filePath string
|
||||
handleLine func(string)
|
||||
stopChan chan struct{}
|
||||
isRunning bool
|
||||
tracker *PositionTracker
|
||||
filePath string
|
||||
handleLine func(string)
|
||||
stopChan chan struct{}
|
||||
isRunning bool
|
||||
tracker *PositionTracker
|
||||
}
|
||||
|
||||
func NewLogTailer(filePath string, handleLine func(string)) *LogTailer {
|
||||
@@ -30,10 +30,9 @@ func (t *LogTailer) Start() {
|
||||
t.isRunning = true
|
||||
|
||||
go func() {
|
||||
// Load last position from tracker
|
||||
pos, err := t.tracker.LoadPosition()
|
||||
if err != nil {
|
||||
pos = &LogPosition{} // Start from beginning if error
|
||||
pos = &LogPosition{}
|
||||
}
|
||||
lastSize := pos.LastPosition
|
||||
|
||||
@@ -43,7 +42,6 @@ func (t *LogTailer) Start() {
|
||||
t.isRunning = false
|
||||
return
|
||||
default:
|
||||
// Try to open and read the file
|
||||
if file, err := os.Open(t.filePath); err == nil {
|
||||
stat, err := file.Stat()
|
||||
if err != nil {
|
||||
@@ -52,12 +50,10 @@ func (t *LogTailer) Start() {
|
||||
continue
|
||||
}
|
||||
|
||||
// If file was truncated, start from beginning
|
||||
if stat.Size() < lastSize {
|
||||
lastSize = 0
|
||||
}
|
||||
|
||||
// Seek to last read position
|
||||
if lastSize > 0 {
|
||||
file.Seek(lastSize, 0)
|
||||
}
|
||||
@@ -66,9 +62,8 @@ func (t *LogTailer) Start() {
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
t.handleLine(line)
|
||||
lastSize, _ = file.Seek(0, 1) // Get current position
|
||||
|
||||
// Save position periodically
|
||||
lastSize, _ = file.Seek(0, 1)
|
||||
|
||||
t.tracker.SavePosition(&LogPosition{
|
||||
LastPosition: lastSize,
|
||||
LastRead: line,
|
||||
@@ -78,7 +73,6 @@ func (t *LogTailer) Start() {
|
||||
file.Close()
|
||||
}
|
||||
|
||||
// Wait before next attempt
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
}
|
||||
@@ -90,4 +84,4 @@ func (t *LogTailer) Stop() {
|
||||
return
|
||||
}
|
||||
close(t.stopChan)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ import (
|
||||
)
|
||||
|
||||
type LogPosition struct {
|
||||
LastPosition int64 `json:"last_position"`
|
||||
LastRead string `json:"last_read"`
|
||||
LastPosition int64 `json:"last_position"`
|
||||
LastRead string `json:"last_read"`
|
||||
}
|
||||
|
||||
type PositionTracker struct {
|
||||
@@ -16,11 +16,10 @@ type PositionTracker struct {
|
||||
}
|
||||
|
||||
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,
|
||||
}
|
||||
@@ -30,7 +29,6 @@ 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
|
||||
@@ -51,4 +49,4 @@ func (t *PositionTracker) SavePosition(pos *LogPosition) error {
|
||||
}
|
||||
|
||||
return os.WriteFile(t.positionFile, data, 0644)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ func TailLogFile(path string, callback func(string)) {
|
||||
file, _ := os.Open(path)
|
||||
defer file.Close()
|
||||
|
||||
file.Seek(0, os.SEEK_END) // Start at end of file
|
||||
file.Seek(0, os.SEEK_END)
|
||||
reader := bufio.NewReader(file)
|
||||
|
||||
for {
|
||||
@@ -88,7 +88,7 @@ func TailLogFile(path string, callback func(string)) {
|
||||
if err == nil {
|
||||
callback(line)
|
||||
} else {
|
||||
time.Sleep(500 * time.Millisecond) // wait for new data
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user