github.com/grafana/tail@v0.0.0-20230510142333-77b18831edf0/cmd/gotail/gotail.go (about) 1 // Copyright (c) 2015 HPE Software Inc. All rights reserved. 2 // Copyright (c) 2013 ActiveState Software Inc. All rights reserved. 3 4 package main 5 6 import ( 7 "flag" 8 "fmt" 9 "os" 10 11 "github.com/grafana/tail" 12 ) 13 14 func args2config() (tail.Config, int64) { 15 config := tail.Config{Follow: true} 16 n := int64(0) 17 maxlinesize := int(0) 18 flag.Int64Var(&n, "n", 0, "tail from the last Nth location") 19 flag.IntVar(&maxlinesize, "max", 0, "max line size") 20 flag.BoolVar(&config.Follow, "f", false, "wait for additional data to be appended to the file") 21 flag.BoolVar(&config.ReOpen, "F", false, "follow, and track file rename/rotation") 22 flag.BoolVar(&config.Poll, "p", false, "use polling, instead of inotify") 23 flag.Parse() 24 if config.ReOpen { 25 config.Follow = true 26 } 27 config.MaxLineSize = maxlinesize 28 return config, n 29 } 30 31 func main() { 32 config, n := args2config() 33 if flag.NFlag() < 1 { 34 fmt.Println("need one or more files as arguments") 35 os.Exit(1) 36 } 37 38 if n != 0 { 39 config.Location = &tail.SeekInfo{-n, os.SEEK_END} 40 } 41 42 done := make(chan bool) 43 for _, filename := range flag.Args() { 44 go tailFile(filename, config, done) 45 } 46 47 for _, _ = range flag.Args() { 48 <-done 49 } 50 } 51 52 func tailFile(filename string, config tail.Config, done chan bool) { 53 defer func() { done <- true }() 54 t, err := tail.TailFile(filename, config) 55 if err != nil { 56 fmt.Println(err) 57 return 58 } 59 for line := range t.Lines { 60 fmt.Println(line.Text) 61 } 62 err = t.Wait() 63 if err != nil { 64 fmt.Println(err) 65 } 66 }