參考連接:git
tail命令用途是依照要求將指定的文件的最後部分輸出到標準設備,一般是終端,通俗講來,就是把某個檔案文件的最後幾行顯示到終端上,假設該檔案有更新,tail會本身主動刷新,確保你看到最新的檔案內容 ,在日誌收集中能夠實時的監測日誌的變化。ide
package main import ( "fmt" "time" "github.com/hpcloud/tail" ) // tailf的用法示例 func main() { fileName := "./my.log" config := tail.Config{ ReOpen: true, // 從新打開 Follow: true, // 是否跟隨 Location: &tail.SeekInfo{Offset: 0, Whence: 2}, // 從文件的哪一個地方開始讀 MustExist: false, // 文件不存在不報錯 Poll: true, } tails, err := tail.TailFile(fileName, config) if err != nil { fmt.Println("tail file failed, err:", err) return } var ( line *tail.Line ok bool ) for { line, ok = <-tails.Lines//遍歷chan,讀取日誌內容 if !ok { fmt.Printf("tail file close reopen, filename:%s\n", tails.Filename) time.Sleep(time.Second) continue } fmt.Println("line:", line.Text) } }
type Tail struct { Filename string Lines chan *Line Config tomb.Tomb // provides: Done, Kill, Dying // contains filtered or unexported fields }
func TailFile(filename string, config Config) (*Tail, error)
TailFile begins 傳入參數:日誌文件的路徑和配置文件,返回一個指向Tail結構體對象的指針。函數
config的數據結構爲:this
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 }
Config 用來定義文件被讀取的方式。3d
Tail結構體中最重要的是Lines字段,他是存儲Line指針來的一個通道。指針
Line的數據結構爲:日誌
type Line struct { Text string Time time.Time Err error // Error from tail }
這個結構體是用來存儲讀取的信息。code
最後簡要總結一下流程:
- 首先初始化配置結構體config
- 調用TailFile函數,並傳入文件路徑和config,返回有個tail的結構體,tail結構體的Lines字段封裝了拿到的信息
- 遍歷tail.Lnes字段,取出信息(注意這裏要循環的取,由於tail能夠實現實時監控)
貼上實戰代碼:
package taillog import ( "fmt" "github.com/hpcloud/tail" ) var ( tailObj *tail.Tail //LogChan chan string ) func Init (filename string)(err error){ config := tail.Config{ // File-specifc Location: &tail.SeekInfo{Offset: 0, Whence: 2}, // 從文件那個位置開始讀 ReOpen: true, //是否從新打開 MustExist: false, // Fail early if the file does notexist Poll: true, // Poll for file changes instead of using inotify Follow: true, // Continue looking for new lines (tail -f) } tailObj,err = tail.TailFile(filename, config) //TailFile(filename, config) if err != nil { fmt.Println("tail file err=", err) return } return } func ReadChan()<-chan *tail.Line{ return tailObj.Lines }