2013-01-08 04:54:49 +08:00
|
|
|
// Copyright (c) 2013 ActiveState Software Inc. All rights reserved.
|
|
|
|
|
2012-10-13 00:05:11 +08:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2013-11-14 09:38:23 +08:00
|
|
|
"flag"
|
2012-10-13 00:05:11 +08:00
|
|
|
"fmt"
|
2012-12-14 21:00:55 +08:00
|
|
|
"github.com/ActiveState/tail"
|
2012-10-13 08:28:04 +08:00
|
|
|
"os"
|
2012-10-13 00:05:11 +08:00
|
|
|
)
|
|
|
|
|
2013-08-10 05:53:37 +08:00
|
|
|
func args2config() (tail.Config, int64) {
|
2012-10-13 08:14:35 +08:00
|
|
|
config := tail.Config{Follow: true}
|
2013-08-10 05:53:37 +08:00
|
|
|
n := int64(0)
|
2014-05-17 09:10:04 +08:00
|
|
|
maxlinesize := int(0)
|
2013-08-10 05:53:37 +08:00
|
|
|
flag.Int64Var(&n, "n", 0, "tail from the last Nth location")
|
2014-05-17 09:10:04 +08:00
|
|
|
flag.IntVar(&maxlinesize, "max", 0, "max line size")
|
2012-10-13 08:14:35 +08:00
|
|
|
flag.BoolVar(&config.Follow, "f", false, "wait for additional data to be appended to the file")
|
|
|
|
flag.BoolVar(&config.ReOpen, "F", false, "follow, and track file rename/rotation")
|
2013-05-30 06:07:53 +08:00
|
|
|
flag.BoolVar(&config.Poll, "p", false, "use polling, instead of inotify")
|
2012-10-13 08:14:35 +08:00
|
|
|
flag.Parse()
|
|
|
|
if config.ReOpen {
|
|
|
|
config.Follow = true
|
|
|
|
}
|
2014-05-17 09:10:04 +08:00
|
|
|
config.MaxLineSize = maxlinesize
|
2013-08-10 05:53:37 +08:00
|
|
|
return config, n
|
2012-10-13 08:14:35 +08:00
|
|
|
}
|
2012-10-13 00:05:11 +08:00
|
|
|
|
|
|
|
func main() {
|
2013-08-10 05:53:37 +08:00
|
|
|
config, n := args2config()
|
2012-10-13 08:28:04 +08:00
|
|
|
if flag.NFlag() < 1 {
|
|
|
|
fmt.Println("need one or more files as arguments")
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
|
2013-08-10 05:53:37 +08:00
|
|
|
if n != 0 {
|
|
|
|
config.Location = &tail.SeekInfo{-n, os.SEEK_END}
|
|
|
|
}
|
|
|
|
|
2012-10-13 08:28:04 +08:00
|
|
|
done := make(chan bool)
|
|
|
|
for _, filename := range flag.Args() {
|
|
|
|
go tailFile(filename, config, done)
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, _ = range flag.Args() {
|
|
|
|
<-done
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func tailFile(filename string, config tail.Config, done chan bool) {
|
|
|
|
defer func() { done <- true }()
|
|
|
|
t, err := tail.TailFile(filename, config)
|
2012-10-13 00:05:11 +08:00
|
|
|
if err != nil {
|
2012-10-13 08:14:35 +08:00
|
|
|
fmt.Println(err)
|
|
|
|
return
|
2012-10-13 00:05:11 +08:00
|
|
|
}
|
|
|
|
for line := range t.Lines {
|
|
|
|
fmt.Println(line.Text)
|
|
|
|
}
|
2012-10-13 08:14:35 +08:00
|
|
|
err = t.Wait()
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err)
|
|
|
|
}
|
2012-10-13 00:05:11 +08:00
|
|
|
}
|