Documentation ¶
Overview ¶
Package tailpipe allows for reading normal files indefinitely. With the tailpipe package, code that uses the standard library's io.Reader interface can be transparently adapted to receive future updates to normal files.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrNotSupported = errors.New("Operation not supported by underlying stream")
The Follow function allows for the creation of a File with an underlying stream that may not implement all interfaces which a File implements. Such Files will return ErrNotSupported when this is the case.
Functions ¶
This section is empty.
Types ¶
type File ¶
type File struct { Rotated <-chan struct{} // contains filtered or unexported fields }
A File represents an open normal file. A File is effectively of infinite length; all reads to the file will block until data are available, even if EOF on the underlying file is reached.
The tailpipe package will attempt to detect when a file has been rotated. Programs that wish to be notified when such a rotation occurs should receive from the Rotated channel.
func Follow ¶
Follow converts an existing io.Reader to a tailpipe.File. This can be useful when opening files with special permissions. In general, the behavior of a tailpipe.File is only suitable for normal files; using Follow on an io.Pipe, net.Conn, or other non-file stream will yield undesirable results.
func Open ¶
Open opens the given file for reading.
Example ¶
package main import ( "bufio" "bytes" "log" "os" "aqwari.net/io/tailpipe" ) func main() { tail, err := tailpipe.Open("/var/log/messages") if err != nil { log.Fatal(err) } defer tail.Close() go func() { for range tail.Rotated { log.Printf("file %s rotated; following new file", tail.Name()) } }() scanner := bufio.NewScanner(tail) for scanner.Scan() { if bytes.Contains(scanner.Bytes(), []byte("ntpd")) { if _, err := os.Stdout.Write(scanner.Bytes()); err != nil { break } } } }
Output:
func (*File) Close ¶
Close closes the underlying file or stream. It also has the side effect of closing the File's Rotated channel. Close is safe to call multiple times.
func (*File) Name ¶
Name returns the name of the underlying file, if available. If the underlying stream does not have a name, Name returns an empty string.
func (*File) Read ¶
Read reads up to len(p) bytes into p. If end-of-file is reached, Read will block until new data are available. Read returns the number of bytes read and any errors other than io.EOF.
If the underlying stream is an *os.File, Read will attempt to detect if it has been replaced, such as during log rotation. If so, Read will re-open the file at the original path provided to Open. Re-opening does not occur until the old file is exhausted.
Notes ¶
Bugs ¶
a File's Rotated channel should not be relied upon to provide an accurate count of file rotations; because the tailpipe will only perform a non-blocking send on the Rotated channel, a goroutine may miss a new notification while it is responding to a previous notification. This is addressed by buffering the channel, but can still be a problem with files that are rotated very frequently.