Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"tail -f"-like generator

Tags:

generator

file

go

I had this convenient function in Python:

def follow(path):
    with open(self.path) as lines:
        lines.seek(0, 2)  # seek to EOF

        while True:
            line = lines.readline()
            if not line:
                time.sleep(0.1)
                    continue
                yield line 

It does something similar to UNIX tail -f: you get last lines of a file as they come. It's convenient because you can get the generator without blocking and pass it to another function.

Then I had to do the same thing in Go. I'm new to this language, so I'm not sure whether what I did is idiomatic/correct enough for Go.

Here is the code:

func Follow(fileName string) chan string {

    out_chan := make(chan string)

    file, err := os.Open(fileName)
    if err != nil {
        log.Fatal(err)
    }

    file.Seek(0, os.SEEK_END)
    bf := bufio.NewReader(file)

    go func() {
        for {
            line, _, _ := bf.ReadLine()

            if len(line) == 0 {
                time.Sleep(10 * time.Millisecond)
            } else {
                out_chan <- string(line)
            }
        }

        defer file.Close()
        close(out_chan)
    }()

    return out_chan
}

Is there any cleaner way to do this in Go? I have a feeling that using an asynchronous call for such a thing is an overkill, and it really bothers me.

like image 523
oopcode Avatar asked Jun 29 '15 16:06

oopcode


1 Answers

Check out this Go package for reading from continuously updated files (tail -f): https://github.com/hpcloud/tail

t, err := tail.TailFile("filename", tail.Config{Follow: true})
for line := range t.Lines {
    fmt.Println(line.Text)
}
like image 128
Tiya Jose Avatar answered Nov 05 '22 08:11

Tiya Jose