func Harvest(path string, output chan FileEvent) { file, reader := fileReader(path) /* Start at the end of the file when first opening. */ file.Seek(0, os.SEEK_END) sleeper := backoff.NewBackoff(100*time.Millisecond, 10*time.Second) for { // Try to read a line from the file line, _, err := reader.ReadLine() if err != nil { // Errors (EOF or otherwise) indicate we should probably // check for file rotation. if shouldReopen(file, path) { file.Close() file, reader = fileReader(path) } else { /* nothing to do, wait. */ sleeper.Wait() } continue } // Got a successful read. Emit the event. sleeper.Reset() output <- FileEvent{path, line} } } /* Harvest */
func fileReader(path string) (*os.File, *bufio.Reader) { sleeper := backoff.NewBackoff(100*time.Millisecond, 10*time.Second) /* Try forever to open this file until successful */ file, err := os.Open(path) for err != nil { fmt.Printf("Failed to open '%s': %s\n", path, err) file, err = os.Open(path) /* TODO(sissel): Check for errors */ sleeper.Wait() } reader := bufio.NewReaderSize(file, 4096) return file, reader }