Dawn's Blogs

分享技术 记录成长

0%

GO语言杂谈 (5) tail包的使用

概述

tail包用于输出文件的最后几行。假设该档案有更新,tail会自己主动刷新,确保你看到最新的档案内容 ,在日志收集中可以实时的监测日志的变化。

介绍

1
func TailFile(filename string, config Config) (*Tail, error)

tail2.TailFile()函数的参数是文件路径配置文件,会生成一个Tail结构体。在Tail结构体中,最重要的属性是文件名Filename和用于存储文件一行Line的通道Lines

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
type Tail struct {
Filename string
Lines chan *Line
Config

file *os.File
reader *bufio.Reader

watcher watch.FileWatcher
changes *watch.FileChanges

tomb.Tomb // provides: Done, Kill, Dying

lk sync.Mutex
}

其中表示文件中一行的结构体为Line,这个结构体用于存储读取的一行信息:

1
2
3
4
5
type Line struct {
Text string
Time time.Time
Err error // Error from tail
}

配置信息结构体为Config,用于指定文件被tail的方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Config is used to specify how a file must be tailed.
type Config struct {
// File-specifc
Location *SeekInfo // Seek to this location before tailing
ReOpen bool // Reopen recreated files (tail -F)
MustExist bool // Fail early if the file does not exist
Poll bool // Poll for file changes instead of using inotify
Pipe bool // Is a named pipe (mkfifo)
RateLimiter *ratelimiter.LeakyBucket

// Generic IO
Follow bool // Continue looking for new lines (tail -f)
MaxLineSize int // If non-zero, split longer lines into multiple lines

// Logger, when nil, is set to tail.DefaultLogger
// To disable logging: set field to tail.DiscardingLogger
Logger logger
}

总结

总结一下tail的使用流程:

  1. 首先定义Config结构体,初始化配置文件
  2. 利用TailFile函数得到Tail结构体,Tail结构体中的Lines封装了拿到的信息
  3. 循环遍历Tail.Lines,取出信息,可以实现实时监控

实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package main

import (
"fmt"
"github.com/hpcloud/tail"
"os"
"time"
)

func main() {
fileName := "log.txt"
tails, err := tail.TailFile(fileName, tail.Config{
Location: &tail.SeekInfo{ // 从文件的哪个地方开始读取
Offset: 0,
Whence: os.SEEK_END,
},
ReOpen: true, // 重新打开文件
MustExist: false, // 文件不存在不报错
Follow: true, // 进行跟随
Poll: true,
})
if err != nil {
fmt.Println("tail file failed, err:", err)
return
}

for {
// 遍历chan,读取日志内容
line, ok := <-tails.Lines
if !ok {
fmt.Printf("tail file close reopen, filename:%s\n", tails.Filename)
time.Sleep(time.Second)
continue
}
fmt.Println("line:", line.Text)
}
}