func NewTail(parser Parser, maxBackfill int64, path string, offsetPath string, offset int64) *Tail { tail := new(Tail) tail.Path = path tail.offset = offset tail.OffsetPath = offsetPath tail.Parser = parser tracker := watch.NewInotifyTracker() w, err := tracker.NewWatcher() if err != nil { return nil } tail.Watcher = watch.NewInotifyFileWatcher(path, w) tail.LoadOffset() tail.maxBackfill = maxBackfill handle, err := os.Open(path) if err != nil { logs.Debug("Can't open file: ", path) return nil } else { tail.handle = handle } tail.seek() return tail }
// TailFile begins tailing the file. Output stream is made available // via the `Tail.Lines` channel. To handle errors during tailing, // invoke the `Wait` or `Err` method after finishing reading from the // `Lines` channel. func TailFile(filename string, config Config) (*Tail, error) { if config.ReOpen && !config.Follow { util.Fatal("cannot set ReOpen without Follow.") } t := &Tail{ Filename: filename, Lines: make(chan *Line), Config: config, } // when Logger was not specified in config, use default logger if t.Logger == nil { t.Logger = log.New(os.Stderr, "", log.LstdFlags) } if t.Poll { t.watcher = watch.NewPollingFileWatcher(filename) } else { t.tracker = watch.NewInotifyTracker() w, err := t.tracker.NewWatcher() if err != nil { return nil, err } t.watcher = watch.NewInotifyFileWatcher(filename, w) } if t.MustExist { var err error t.file, err = OpenFile(t.Filename) if err != nil { return nil, err } } go t.tailFileSync() return t, nil }