golang基础-tailf日志组件使用

来源:互联网 发布:c语言函数规则 编辑:程序博客网 时间:2024/06/03 01:48

git上log日志组件
https://github.com/hpcloud/tail/blob/master/tail.go

我们写个test来测试下这个组件

package mainimport (    "fmt"    "github.com/hpcloud/tail"    "time")func main() {    filename := "E:\\develop\\kafka\\kafka_2.12-1.0.0\\config\\server.properties"    tails, err := tail.TailFile(filename, tail.Config{        ReOpen:    true,        Follow:    true,        // Location:  &tail.SeekInfo{Offset: 0, Whence: 2},        MustExist: false,        Poll:      true,    })    if err != nil {        fmt.Println("tail file err:", err)        return    }    var msg *tail.Line    var ok bool    for true {        msg, ok = <-tails.Lines        if !ok {            fmt.Printf("tail file close reopen, filename:%s\n", tails.Filename)            time.Sleep(100 * time.Millisecond)            continue        }        fmt.Println("msg:", msg)    }}

执行代码会在终端输出如下该文件的信息:

PS E:\golang\go_pro\src\safly> go run safly.gomsg: &{# Licensed to the Apache Software Foundation (ASF) under one or more 2017-11-18 19:22:49.1946892 +0800 CST <nil>}msg: &{# contributor license agreements.  See the NOTICE file distributed with 2017-11-18 19:22:49.1946892 +0800 CST <nil>}msg: &{# this work for additional information regarding copyright ownership. 2017-11-18 19:22:49.2086992 +0800 CST <nil>}msg: &{# The ASF licenses this file to You under the Apache License, Version 2.0 2017-11-18 19:22:49.2102004 +0800 CST <nil>}。。。。。。省略

我们看看源码tailf.go的执行流程:

func TailFile(filename string, config Config) (*Tail, error) {    if config.ReOpen && !config.Follow {        util.Fatal("cannot set ReOpen without Follow.")    }    t := &Tail{        Filename: filename,        Lines:    make(chan *Line),        Config:   config,    }    // when Logger was not specified in config, use default logger    if t.Logger == nil {        t.Logger = log.New(os.Stderr, "", log.LstdFlags)    }    if t.Poll {        t.watcher = watch.NewPollingFileWatcher(filename)    } else {        t.watcher = watch.NewInotifyFileWatcher(filename)    }    if t.MustExist {        var err error        t.file, err = OpenFile(t.Filename)        if err != nil {            return nil, err        }    }    go t.tailFileSync()    return t, nil}

在最后go t.tailFileSync()启动goroutine
在tailFileSync方法中

tail.openReader()

看看做了什么操作?

func (tail *Tail) openReader() {    if tail.MaxLineSize > 0 {        // add 2 to account for newline characters        tail.reader = bufio.NewReaderSize(tail.file, tail.MaxLineSize+2)    } else {        tail.reader = bufio.NewReader(tail.file)    }}

创建reader,然后for读取line, err := tail.readLine()

然后写入chan 中

// Process `line` even if err is EOF.        if err == nil {            cooloff := !tail.sendLine(line)            if cooloff {                // Wait a second before seeking till the end of                // file when rate limit is reached.                msg := ("Too much log activity; waiting a second " +                    "before resuming tailing")                tail.Lines <- &Line{msg, time.Now(), errors.New(msg)}                select {                case <-time.After(time.Second):                case <-tail.Dying():                    return                }                if err := tail.seekEnd(); err != nil {                    tail.Kill(err)                    return                }            }}

tail.Lines <- &Line{msg, time.Now(), errors.New(msg)}中的Lines是在Tail定义的chan

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}
原创粉丝点击