tail.Location is now the most customizable
as it is now a tuple; (offset, whence) from os.Seek
This commit is contained in:
parent
8d9c6e4ce1
commit
faf14146e7
|
@ -9,9 +9,10 @@ import (
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
func args2config() tail.Config {
|
func args2config() (tail.Config, int64) {
|
||||||
config := tail.Config{Follow: true}
|
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.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.ReOpen, "F", false, "follow, and track file rename/rotation")
|
||||||
flag.BoolVar(&config.Poll, "p", false, "use polling, instead of inotify")
|
flag.BoolVar(&config.Poll, "p", false, "use polling, instead of inotify")
|
||||||
|
@ -19,16 +20,20 @@ func args2config() tail.Config {
|
||||||
if config.ReOpen {
|
if config.ReOpen {
|
||||||
config.Follow = true
|
config.Follow = true
|
||||||
}
|
}
|
||||||
return config
|
return config, n
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
config := args2config()
|
config, n := args2config()
|
||||||
if flag.NFlag() < 1 {
|
if flag.NFlag() < 1 {
|
||||||
fmt.Println("need one or more files as arguments")
|
fmt.Println("need one or more files as arguments")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if n != 0 {
|
||||||
|
config.Location = &tail.SeekInfo{-n, os.SEEK_END}
|
||||||
|
}
|
||||||
|
|
||||||
done := make(chan bool)
|
done := make(chan bool)
|
||||||
for _, filename := range flag.Args() {
|
for _, filename := range flag.Args() {
|
||||||
go tailFile(filename, config, done)
|
go tailFile(filename, config, done)
|
||||||
|
|
22
tail.go
22
tail.go
|
@ -24,11 +24,14 @@ type Line struct {
|
||||||
// log line itself.
|
// log line itself.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SeekInfo struct {
|
||||||
|
Offset int64
|
||||||
|
Whence int // os.SEEK_*
|
||||||
|
}
|
||||||
|
|
||||||
// Config is used to specify how a file must be tailed.
|
// Config is used to specify how a file must be tailed.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Location int64 // For positive location, tail after first N
|
Location *SeekInfo // Seek before tailing
|
||||||
// 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)
|
Follow bool // Continue looking for new lines (tail -f)
|
||||||
ReOpen bool // Reopen recreated files (tail -F)
|
ReOpen bool // Reopen recreated files (tail -F)
|
||||||
MustExist bool // Fail early if the file does not exist
|
MustExist bool // Fail early if the file does not exist
|
||||||
|
@ -141,16 +144,9 @@ func (tail *Tail) tailFileSync() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Seek to requested location on first open of the file.
|
// Seek to requested location on first open of the file.
|
||||||
if tail.Location != -1 {
|
if tail.Location != nil {
|
||||||
var err error
|
_, err := tail.file.Seek(tail.Location.Offset, tail.Location.Whence)
|
||||||
switch {
|
// log.Printf("Seeked %s - %+v\n", tail.Filename, tail.Location)
|
||||||
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 err != nil {
|
if err != nil {
|
||||||
tail.Killf("Seek error on %s: %s", tail.Filename, err)
|
tail.Killf("Seek error on %s: %s", tail.Filename, err)
|
||||||
return
|
return
|
||||||
|
|
Loading…
Reference in New Issue