我正在尝试解析一些日志文件,因为它们是在Go中编写的,但是我不确定如何在不检查更改的情况下一次又一次地重新读取文件的情况下完成此操作.
我希望能够读到EOF,等到下一行写入并再次读到EOF等等.感觉有点像tail -f
外观.
Rei*_*ica 49
我写了一个Go包 - github.com/ActiveState/tail - 就是这么做的.
t, err := tail.TailFile("/var/log/nginx.log", tail.Config{Follow: true})
for line := range t.Lines {
fmt.Println(line.Text)
}
Run Code Online (Sandbox Code Playgroud)
...
引用kostix的答案:
在现实生活中,文件可能会被截断,替换或重命名(因为这就像logrotate这样的工具应该这样做).
如果文件被截断,它将自动重新打开.要支持重新打开重命名的文件(由于logrotate等),您可以设置Config.ReOpen,即:
t, err := tail.TailFile("/var/log/nginx.log", tail.Config{
Follow: true,
ReOpen: true})
for line := range t.Lines {
fmt.Println(line.Text)
}
Run Code Online (Sandbox Code Playgroud)
Config.ReOpen
类似于tail -F
(大写字母F):
-F The -F option implies the -f option, but tail will also check to see if the file being followed has been
renamed or rotated. The file is closed and reopened when tail detects that the filename being read from
has a new inode number. The -F option is ignored if reading from standard input rather than a file.
Run Code Online (Sandbox Code Playgroud)
您必须观察文件以进行更改(使用特定于操作系统的子系统来完成此操作)或定期轮询以查看其修改时间(和大小)是否已更改.在任何一种情况下,在读取另一块数据后,您都会记住文件偏移量,并在检测到更改后读取另一个块之前将其恢复.
但请注意,这似乎只是在纸上很容易:在现实生活中,文件可能会被截断,替换或重命名(因为这就是工具logrotate
应该做的事情).
有关此问题的更多讨论,请参阅此问题.
小智 5
一个简单的例子:
package main
import (
"bufio"
"fmt"
"io"
"os"
"time"
)
func tail(filename string, out io.Writer) {
f, err := os.Open(filename)
if err != nil {
panic(err)
}
defer f.Close()
r := bufio.NewReader(f)
info, err := f.Stat()
if err != nil {
panic(err)
}
oldSize := info.Size()
for {
for line, prefix, err := r.ReadLine(); err != io.EOF; line, prefix, err = r.ReadLine() {
if prefix {
fmt.Fprint(out, string(line))
} else {
fmt.Fprintln(out, string(line))
}
}
pos, err := f.Seek(0, io.SeekCurrent)
if err != nil {
panic(err)
}
for {
time.Sleep(time.Second)
newinfo, err := f.Stat()
if err != nil {
panic(err)
}
newSize := newinfo.Size()
if newSize != oldSize {
if newSize < oldSize {
f.Seek(0, 0)
} else {
f.Seek(pos, io.SeekStart)
}
r = bufio.NewReader(f)
oldSize = newSize
break
}
}
}
}
func main() {
tail("x.txt", os.Stdout)
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
17565 次 |
最近记录: |