Lines Matching refs:tail

4 package tail  package
143 func (tail *Tail) Tell() (int64, error) {
144 tail.fileMtx.Lock()
145 f := tail.file
146 tail.fileMtx.Unlock()
155 tail.lk.Lock()
156 defer tail.lk.Unlock()
157 if tail.reader == nil {
161 offset -= int64(tail.reader.Buffered())
167 func (tail *Tail) Size() (int64, error) {
168 tail.fileMtx.Lock()
169 f := tail.file
170 tail.fileMtx.Unlock()
183 func (tail *Tail) Stop() error {
184 tail.Kill(nil)
185 return tail.Wait()
189 func (tail *Tail) StopAtEOF() error {
190 tail.Kill(errStopAtEOF)
191 return tail.Wait()
196 func (tail *Tail) close() {
197 close(tail.Lines)
198 tail.closeFile()
201 func (tail *Tail) closeFile() {
202 tail.fileMtx.Lock()
203 defer tail.fileMtx.Unlock()
204 if tail.file != nil {
205 tail.file.Close()
206 tail.file = nil
210 func (tail *Tail) reopen(truncated bool) error {
216 cf, err := tail.file.Stat()
223 tail.closeFile()
226 tail.fileMtx.Lock()
227 tail.file, err = OpenFile(tail.Filename)
228 tail.fileMtx.Unlock()
231 tail.Logger.Printf("Waiting for %s to appear...", tail.Filename)
232 if err := tail.watcher.BlockUntilExists(&tail.Tomb); err != nil {
236 return fmt.Errorf("Failed to detect creation of %s: %s", tail.Filename, err)
240 return fmt.Errorf("Unable to open file %s: %s", tail.Filename, err)
244 nf, err := tail.file.Stat()
246 tail.Logger.Print("Failed to stat new file to be tailed, will try to open it again")
247 tail.closeFile()
260 tail.closeFile()
262 case <-tail.Tomb.Dying():
271 func (tail *Tail) readLine() (string, error) {
272 tail.lk.Lock()
273 line, err := tail.reader.ReadString('\n')
274 tail.lk.Unlock()
287 func (tail *Tail) tailFileSync() {
288 defer tail.Done()
289 defer tail.close()
291 if !tail.MustExist {
293 err := tail.reopen(true)
296 tail.Kill(err)
303 if tail.Location != nil {
304 _, err := tail.file.Seek(tail.Location.Offset, tail.Location.Whence)
305 tail.Logger.Printf("Seeked %s - %+v\n", tail.Filename, tail.Location)
307 tail.Killf("Seek error on %s: %s", tail.Filename, err)
312 tail.openReader()
321 if !tail.Pipe {
323 offset, err = tail.Tell()
325 tail.Kill(err)
330 line, err := tail.readLine()
334 cooloff := !tail.sendLine(line)
340 tail.Lines <- &Line{msg, time.Now(), errors.New(msg)}
343 case <-tail.Dying():
346 if err := tail.seekEnd(); err != nil {
347 tail.Kill(err)
352 if !tail.Follow {
354 tail.sendLine(line)
359 if tail.Follow && line != "" {
362 err := tail.seekTo(SeekInfo{Offset: offset, Whence: 0})
364 tail.Kill(err)
374 err = tail.finishDelete()
377 tail.Kill(err)
386 oneMoreRun, err = tail.waitForChanges()
389 tail.Kill(err)
395 tail.Killf("Error reading %s: %s", tail.Filename, err)
400 case <-tail.Dying():
401 if tail.Err() == errStopAtEOF {
413 func (tail *Tail) waitForChanges() (bool, error) {
414 if tail.changes == nil {
415 pos, err := tail.file.Seek(0, io.SeekCurrent)
419 tail.changes, err = tail.watcher.ChangeEvents(&tail.Tomb, pos)
426 case <-tail.changes.Modified:
428 case <-tail.changes.Deleted:
432 case <-tail.changes.Truncated:
434 tail.Logger.Printf("Re-opening truncated file %s ...", tail.Filename)
435 if err := tail.reopen(true); err != nil {
438 tail.Logger.Printf("Successfully reopened truncated %s", tail.Filename)
439 tail.openReader()
441 case <-tail.Dying():
447 func (tail *Tail) finishDelete() error {
448 tail.changes = nil
449 if tail.ReOpen {
451 tail.Logger.Printf("Re-opening moved/deleted file %s ...", tail.Filename)
452 if err := tail.reopen(false); err != nil {
455 tail.Logger.Printf("Successfully reopened %s", tail.Filename)
456 tail.openReader()
459 tail.Logger.Printf("Stopping tail as file no longer exists: %s", tail.Filename)
464 func (tail *Tail) openReader() {
465 if tail.MaxLineSize > 0 {
467 tail.reader = bufio.NewReaderSize(tail.file, tail.MaxLineSize+2)
469 tail.reader = bufio.NewReader(tail.file)
473 func (tail *Tail) seekEnd() error {
474 return tail.seekTo(SeekInfo{Offset: 0, Whence: os.SEEK_END})
477 func (tail *Tail) seekTo(pos SeekInfo) error {
478 _, err := tail.file.Seek(pos.Offset, pos.Whence)
480 return fmt.Errorf("Seek error on %s: %s", tail.Filename, err)
483 tail.reader.Reset(tail.file)
489 func (tail *Tail) sendLine(line string) bool {
494 if tail.MaxLineSize > 0 && len(line) > tail.MaxLineSize {
495 lines = util.PartitionString(line, tail.MaxLineSize)
499 tail.Lines <- &Line{line, now, nil}
502 if tail.Config.RateLimiter != nil {
503 ok := tail.Config.RateLimiter.Pour(uint16(len(lines)))
505 tail.Logger.Printf("Leaky bucket full (%v); entering 1s cooloff period.\n",
506 tail.Filename)
517 func (tail *Tail) Cleanup() {
518 watch.Cleanup(tail.Filename)