tailpipe

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 14, 2016 License: MIT Imports: 5 Imported by: 1

README

Build Status GoDoc

The tailpipe package provides an implementation of tail -F for Go. In effect, it produces files that are infinite length, and re-opens the file when it is changed, such as during log rotation. It can be used for programs that need to watch log files indefinitely.

There are several tail packages for Go available. However, most packages do not preserve the io.Reader interface, instead opting for a line-oriented approach involving chan string. By preserving the io.Reader interface, this package composes better with the standard library.

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

View Source
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

func Follow(r io.Reader) *File

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

func Open(path string) (*File, error)

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

func (f *File) Close() error

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

func (f *File) Name() string

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

func (f *File) Read(p []byte) (n int, err error)

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.

func (*File) Seek

func (f *File) Seek(offset int64, whence int) (int64, error)

Seek calls Seek on the underlying stream. If the underlying stream does not provide a Seek method, ErrNotSupported is returned.

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL