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"
|
||||
)
|
||||
|
||||
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
34
tail.go
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue