update readme, comments; gofmt

This commit is contained in:
Sridhar Ratnakumar 2013-05-29 16:32:01 -07:00
parent 4deef2319f
commit 92ad722d56
3 changed files with 26 additions and 31 deletions

View File

@ -11,23 +11,17 @@ for line := range t.Lines {
See [API documentation](http://godoc.org/github.com/ActiveState/tail).
## Log rotation
Tail comes with full support for truncation/move detection as it is
designed to work with log rotation tools.
## Installing
go get github.com/ActiveState/tail
## Building
To build and test the package,
make test
To build the toy command-line program `gotail`,
cd cmd/gotail
make
./gotail -h
go get github.com/ActiveState/tail/...
## TODO
* Support arbitrary values for `Location`
* Arbitrary values for `Location`
* `Location` could be specified in both lines and bytes metrics.

23
tail.go
View File

@ -22,7 +22,7 @@ type Line struct {
Time time.Time
}
// Tail configuration
// Config is used to specify how a file must be tailed.
type Config struct {
Location int // Tail from last N lines (tail -n)
Follow bool // Continue looking for new lines (tail -f)
@ -45,10 +45,10 @@ type Tail struct {
tomb.Tomb // provides: Done, Kill, Dying
}
// TailFile begins tailing the file with the specified
// configuration. Output stream is made available via the `Tail.Lines`
// channel. To handle errors during tailing, invoke the `Wait` method
// after finishing reading from the `Lines` channel.
// TailFile begins tailing the file. Output stream is made available
// via the `Tail.Lines` channel. To handle errors during tailing,
// invoke the `Wait` or `Err` method after finishing reading from the
// `Lines` channel.
func TailFile(filename string, config Config) (*Tail, error) {
if !(config.Location == 0 || config.Location == -1) {
panic("only 0/-1 values are supported for Location.")
@ -154,7 +154,7 @@ func (tail *Tail) tailFileSync() {
for {
line, err := tail.readLine()
switch(err) {
switch err {
case nil:
if line != nil {
tail.sendLine(line)
@ -164,7 +164,7 @@ func (tail *Tail) tailFileSync() {
// available. Wait strategy is based on the `tail.watcher`
// implementation (inotify or polling).
err := tail.waitForChanges()
if err != nil {
if err != nil {
if err != ErrStop {
tail.Kill(err)
}
@ -184,8 +184,8 @@ func (tail *Tail) tailFileSync() {
}
// waitForChanges waits until the file has been appended, deleted,
// moved or truncated. When moved, deleted or truncated - the file
// will be re-opened if ReOpen is true.
// moved or truncated. When moved or deleted - the file will be
// reopened if ReOpen is true. Truncated files are always reopened.
func (tail *Tail) waitForChanges() error {
if tail.changes == nil {
st, err := tail.file.Stat()
@ -197,6 +197,7 @@ func (tail *Tail) waitForChanges() error {
select {
case <-tail.changes.Modified:
return nil
case <-tail.changes.Deleted:
tail.changes = nil
if tail.ReOpen {
@ -216,7 +217,7 @@ func (tail *Tail) waitForChanges() error {
// Always reopen truncated files (Follow is true)
log.Printf("Re-opening truncated file %s ...", tail.Filename)
if err := tail.reopen(); err != nil {
return err
return err
}
log.Printf("Successfully reopened truncated %s", tail.Filename)
tail.reader = bufio.NewReader(tail.file)
@ -224,7 +225,7 @@ func (tail *Tail) waitForChanges() error {
case <-tail.Dying():
return ErrStop
}
return nil
panic("unreachable")
}
// sendLine sends the line(s) to Lines channel, splitting longer lines

View File

@ -9,13 +9,13 @@ import (
// FileWatcher monitors file-level events.
type FileWatcher interface {
// BlockUntilExists blocks until the missing file comes into
// existence. If the file already exists, returns immediately.
// BlockUntilExists blocks until the file comes into existence.
BlockUntilExists(tomb.Tomb) error
// ChangeEvents returns a channel of events corresponding to the
// times the file is ready to be read. The channel will be closed
// if the file gets deleted, renamed or truncated.
// ChangeEvents reports on changes to a file, be it modification,
// deletion, renames or truncations. Returned FileChanges group of
// channels will be closed, thus become unusable, after a deletion
// or truncation event.
ChangeEvents(tomb.Tomb, os.FileInfo) *FileChanges
}