Lines Matching refs:tail

4 package tail  package
135 func (tail *Tail) Tell() (offset int64, err error) {
136 if tail.file == nil {
139 offset, err = tail.file.Seek(0, os.SEEK_CUR)
144 tail.lk.Lock()
145 defer tail.lk.Unlock()
146 if tail.reader == nil {
150 offset -= int64(tail.reader.Buffered())
155 func (tail *Tail) Stop() error {
156 tail.Kill(nil)
157 return tail.Wait()
161 func (tail *Tail) StopAtEOF() error {
162 tail.Kill(errStopAtEOF)
163 return tail.Wait()
168 func (tail *Tail) close() {
169 close(tail.Bytes)
170 tail.closeFile()
173 func (tail *Tail) closeFile() {
174 if tail.file != nil {
175 tail.file.Close()
176 tail.file = nil
180 func (tail *Tail) reopen() error {
181 tail.closeFile()
184 tail.file, err = OpenFile(tail.Filename)
187 tail.Logger.Printf("Waiting for %s to appear...", tail.Filename)
188 if err := tail.watcher.BlockUntilExists(&tail.Tomb); err != nil {
192 return fmt.Errorf("Failed to detect creation of %s: %s", tail.Filename, err)
196 return fmt.Errorf("Unable to open file %s: %s", tail.Filename, err)
203 func (tail *Tail) readLine() ([]byte, error) {
204 tail.lk.Lock()
205 defer tail.lk.Unlock()
206 b, err := tail.reader.ReadByte()
210 func (tail *Tail) tailFileSync() {
211 defer tail.Done()
212 defer tail.close()
214 if !tail.MustExist {
216 err := tail.reopen()
219 tail.Kill(err)
226 if tail.Location != nil {
227 _, err := tail.file.Seek(tail.Location.Offset, tail.Location.Whence)
228 tail.Logger.Printf("Seeked %s - %+v\n", tail.Filename, tail.Location)
230 tail.Killf("Seek error on %s: %s", tail.Filename, err)
235 tail.openReader()
243 if !tail.Pipe {
245 offset, err = tail.Tell()
247 tail.Kill(err)
252 line, err := tail.readLine()
256 cooloff := !tail.sendChunk(line)
262 tail.Bytes <- &Chunk{[]byte(msg), time.Now(), errors.New(msg)}
265 case <-tail.Dying():
268 if err := tail.seekEnd(); err != nil {
269 tail.Kill(err)
274 if !tail.Follow {
276 tail.sendChunk(line)
281 if tail.Follow && len(line) > 0 {
284 err := tail.seekTo(SeekInfo{Offset: offset, Whence: 0})
286 tail.Kill(err)
294 err := tail.waitForChanges()
297 tail.Kill(err)
303 tail.Killf("Error reading %s: %s", tail.Filename, err)
308 case <-tail.Dying():
309 if tail.Err() == errStopAtEOF {
321 func (tail *Tail) waitForChanges() error {
322 if tail.changes == nil {
323 pos, err := tail.file.Seek(0, os.SEEK_CUR)
327 tail.changes, err = tail.watcher.ChangeEvents(&tail.Tomb, pos)
334 case <-tail.changes.Modified:
336 case <-tail.changes.Deleted:
337 tail.changes = nil
338 if tail.ReOpen {
340 tail.Logger.Printf("Re-opening moved/deleted file %s ...", tail.Filename)
341 if err := tail.reopen(); err != nil {
344 tail.Logger.Printf("Successfully reopened %s", tail.Filename)
345 tail.openReader()
348 tail.Logger.Printf("Stopping tail as file no longer exists: %s", tail.Filename)
351 case <-tail.changes.Truncated:
353 tail.Logger.Printf("Re-opening truncated file %s ...", tail.Filename)
354 if err := tail.reopen(); err != nil {
357 tail.Logger.Printf("Successfully reopened truncated %s", tail.Filename)
358 tail.openReader()
360 case <-tail.Dying():
366 func (tail *Tail) openReader() {
367 tail.reader = bufio.NewReader(tail.file)
370 func (tail *Tail) seekEnd() error {
371 return tail.seekTo(SeekInfo{Offset: 0, Whence: os.SEEK_END})
374 func (tail *Tail) seekTo(pos SeekInfo) error {
375 _, err := tail.file.Seek(pos.Offset, pos.Whence)
377 return fmt.Errorf("Seek error on %s: %s", tail.Filename, err)
380 tail.reader.Reset(tail.file)
386 func (tail *Tail) sendChunk(line []byte) bool {
389 tail.Bytes <- &Chunk{line, now, nil}
397 func (tail *Tail) Cleanup() {
398 watch.Cleanup(tail.Filename)