tail.Location is now the most customizable

as it is now a tuple; (offset, whence) from os.Seek
This commit is contained in:
Sridhar Ratnakumar 2013-08-09 14:53:37 -07:00
parent 8d9c6e4ce1
commit faf14146e7
2 changed files with 24 additions and 23 deletions

View File

@ -9,9 +9,10 @@ import (
"os"
)
func args2config() tail.Config {
func args2config() (tail.Config, int64) {
config := tail.Config{Follow: true}
flag.Int64Var(&config.Location, "n", 0, "tail from the last Nth location")
n := int64(0)
flag.Int64Var(&n, "n", 0, "tail from the last Nth location")
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")
flag.BoolVar(&config.Poll, "p", false, "use polling, instead of inotify")
@ -19,16 +20,20 @@ func args2config() tail.Config {
if config.ReOpen {
config.Follow = true
}
return config
return config, n
}
func main() {
config := args2config()
config, n := args2config()
if flag.NFlag() < 1 {
fmt.Println("need one or more files as arguments")
os.Exit(1)
}
if n != 0 {
config.Location = &tail.SeekInfo{-n, os.SEEK_END}
}
done := make(chan bool)
for _, filename := range flag.Args() {
go tailFile(filename, config, done)

34
tail.go
View File

@ -24,17 +24,20 @@ type Line struct {
// log line itself.
}
type SeekInfo struct {
Offset int64
Whence int // os.SEEK_*
}
// Config is used to specify how a file must be tailed.
type Config struct {
Location int64 // For positive location, tail after first N
// lines; for negative, tail from last N lines;
// for zero, tail from end. If -1, do not seek.
Follow bool // Continue looking for new lines (tail -f)
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
MaxLineSize int // If non-zero, split longer lines into multiple lines
LimitRate int64 // If non-zero, limit the rate of read log lines
Location *SeekInfo // Seek before tailing
Follow bool // Continue looking for new lines (tail -f)
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
MaxLineSize int // If non-zero, split longer lines into multiple lines
LimitRate int64 // If non-zero, limit the rate of read log lines
// by this much per second.
}
@ -141,16 +144,9 @@ func (tail *Tail) tailFileSync() {
}
// Seek to requested location on first open of the file.
if tail.Location != -1 {
var err error
switch {
case tail.Location <= 0:
// Seek relative to file end
_, err = tail.file.Seek(tail.Location, os.SEEK_END)
default:
// Seek from file beginning
_, err = tail.file.Seek(tail.Location, os.SEEK_SET)
}
if tail.Location != nil {
_, err := tail.file.Seek(tail.Location.Offset, tail.Location.Whence)
// log.Printf("Seeked %s - %+v\n", tail.Filename, tail.Location)
if err != nil {
tail.Killf("Seek error on %s: %s", tail.Filename, err)
return