package monitor import ( "fmt" "github.com/nxadm/tail" "go.uber.org/zap" "regexp" ) type Monitor interface { Close() error Watch(filename string, filter *regexp.Regexp, lineChan chan<- string) error } func New() *LogMonitor { return &LogMonitor{ cancel: make(chan interface{}), } } type LogMonitor struct { cancel chan interface{} } func (l *LogMonitor) Close() error { close(l.cancel) return nil } func (l *LogMonitor) Watch(filename string, filter *regexp.Regexp, lineChan chan<- string) error { t, err := tail.TailFile(filename, tail.Config{Follow: true, ReOpen: true, Logger: tail.DiscardingLogger}) if err != nil { return fmt.Errorf("unable to begin to tail file '%s': %w", filename, err) } for { select { case line := <-t.Lines: if line.Err != nil { zap.S().Errorf("tail error: %v", err) continue } zap.S().Infof("new line: '%s'", line.Text) if filter.MatchString(line.Text) { lineChan <- line.Text } case <-l.cancel: t.Stop() t.Cleanup() return nil } } return nil }