Skip to content

Commit c3b22e3

Browse files
committed
fix(log): 跟踪日志时支持轮转重开
1 parent 100e30b commit c3b22e3

1 file changed

Lines changed: 57 additions & 22 deletions

File tree

cmd/log.go

Lines changed: 57 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -61,33 +61,68 @@ func followLogs(logFile string) {
6161
}
6262
defer file.Close()
6363

64-
file.Seek(0, 2)
64+
offset, err := file.Seek(0, io.SeekEnd)
65+
if err != nil {
66+
fmt.Printf("定位日志失败: %v\n", err)
67+
return
68+
}
6569

6670
buffer := make([]byte, 1024)
67-
done := make(chan bool)
6871

69-
go func() {
70-
for {
71-
select {
72-
case <-done:
72+
for {
73+
select {
74+
case <-sigChan:
75+
return
76+
default:
77+
}
78+
79+
n, err := file.Read(buffer)
80+
if n > 0 {
81+
fmt.Print(string(buffer[:n]))
82+
offset += int64(n)
83+
}
84+
if err == nil {
85+
continue
86+
}
87+
if err == io.EOF {
88+
newFile, newOffset, changed, reopenErr := reopenFollowLogIfNeeded(logFile, file, offset)
89+
if reopenErr != nil {
90+
fmt.Printf("重新打开日志失败: %v\n", reopenErr)
7391
return
74-
default:
75-
n, err := file.Read(buffer)
76-
if err != nil {
77-
if err == io.EOF {
78-
time.Sleep(100 * time.Millisecond)
79-
continue
80-
}
81-
done <- true
82-
return
83-
}
84-
if n > 0 {
85-
fmt.Print(string(buffer[:n]))
86-
}
8792
}
93+
if changed {
94+
file.Close()
95+
file = newFile
96+
offset = newOffset
97+
}
98+
time.Sleep(100 * time.Millisecond)
99+
continue
88100
}
89-
}()
90101

91-
<-sigChan
92-
done <- true
102+
fmt.Printf("读取日志失败: %v\n", err)
103+
return
104+
}
105+
}
106+
107+
// reopenFollowLogIfNeeded 在日志轮转或截断后重新打开当前日志文件。
108+
func reopenFollowLogIfNeeded(logFile string, currentFile *os.File, offset int64) (*os.File, int64, bool, error) {
109+
currentInfo, currentErr := currentFile.Stat()
110+
pathInfo, err := os.Stat(logFile)
111+
if err != nil {
112+
if os.IsNotExist(err) {
113+
return currentFile, offset, false, nil
114+
}
115+
return currentFile, offset, false, err
116+
}
117+
118+
changed := currentErr != nil || !os.SameFile(currentInfo, pathInfo) || pathInfo.Size() < offset
119+
if !changed {
120+
return currentFile, offset, false, nil
121+
}
122+
123+
newFile, err := os.Open(logFile)
124+
if err != nil {
125+
return currentFile, offset, false, err
126+
}
127+
return newFile, 0, true, nil
93128
}

0 commit comments

Comments
 (0)