tail

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Nov 26, 2018 License: MIT Imports: 4 Imported by: 1

README

tail GoDoc Go Report Card CircleCI Coverage Status

Go package tail implements behaviour of tail -n 0 -F path to follow rotated log files using polling.

Most existing solutions for Go have race condition issues and occasionally may lose lines from tracked file - such bugs are hard to fix without massive changes in their architecture, so it turns out to be easier to reimplement this functionality from scratch to make it work reliable and don't lose data.

This package tries to log messages in same way as tail.

Unlike tail tool it does track renamed/removed file contents up to the moment new file will be created with original name - this ensure no data will be lost in case log rotation is done by external tool (i.e. not the one which write to log file) and thus original log file may be appended between rename/removal and reopening.

Unlike tail it does not support file truncation. While this can't work reliable, truncate support may be added in the future.

Installation

go get github.com/powerman/tail

Documentation

Overview

Package tail implements behaviour of `tail -n 0 -F path`.

Example
package main

import (
	"context"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"time"

	"github.com/powerman/tail"
)

func main() {
	f, _ := ioutil.TempFile("", "gotest")
	_, _ = f.Write([]byte("first"))

	ctx, cancel := context.WithCancel(context.Background())
	t := tail.Follow(ctx, tail.LoggerFunc(log.Printf), f.Name(),
		tail.PollTimeout(2*time.Second)) // increase timeout to avoid error from io.Copy

	go func() {
		time.Sleep(time.Second) // ensure tail has started

		_, _ = f.Write([]byte("second\n"))
		_ = os.Remove(f.Name())
		time.Sleep(time.Second) // ensure tail notice removed file

		_, _ = f.Write([]byte("third\n"))
		f.Close()
		time.Sleep(time.Second) // ensure tail read file before being cancelled

		cancel() // tell tail to cancel and return io.EOF
	}()

	_, err := io.Copy(os.Stdout, t)
	fmt.Println("err:", err)
}
Output:

second
third
err: <nil>

Index

Examples

Constants

View Source
const (
	DefaultPollDelay   = 200 * time.Millisecond
	DefaultPollTimeout = time.Second
)

Defaults for corresponding options.

Variables

This section is empty.

Functions

This section is empty.

Types

type Logger

type Logger interface {
	Printf(format string, v ...interface{})
}

Logger is an interface used to log tail state changes.

type LoggerFunc

type LoggerFunc func(format string, v ...interface{})

The LoggerFunc type is an adapter to allow the use of ordinary function as a logger. If f is a function with the appropriate signature, LoggerFunc(f) is a Logger that calls f.

func (LoggerFunc) Printf

func (f LoggerFunc) Printf(format string, v ...interface{})

Printf implements Logger interface.

type Option

type Option interface {
	// contains filtered or unexported methods
}

Option let you change Tail behaviour.

func PollDelay

func PollDelay(d time.Duration) Option

PollDelay let you change delay between polling to save CPU.

func PollTimeout

func PollTimeout(d time.Duration) Option

PollTimeout let you change how long to wait before return error when failed to open or read file.

type Tail

type Tail struct {
	// contains filtered or unexported fields
}

Tail is an io.Reader with `tail -n 0 -F path` behaviour.

Unlike `tail` it does track renamed/removed file contents up to the moment new file will be created with original name - this ensure no data will be lost in case log rotation is done by external tool (not the one which write to log file) and thus original log file may be appended between rename/removal and reopening.

Unlike `tail` it does not support file truncation. While this can't work reliable, truncate support may be added in the future.

func Follow

func Follow(ctx context.Context, log Logger, path string, options ...Option) *Tail

Follow starts tracking the path using polling.

If path already exists tracking begins from the end of the file.

Supported path types: usual file, FIFO and symlink to usual or FIFO.

func (*Tail) Read

func (t *Tail) Read(p []byte) (int, error)

Read returns appended data as the file grows, keep trying to open a file if it is inaccessible, and continue reading from beginning of the file when it will became accessible (e.g. after log rotation).

Returned data is not guaranteed to contain full lines of text.

If Read returns any error except io.EOF, then following Read will return either some data or io.EOF.

Read may return 0, nil only if len(p) == 0.

Read will return io.EOF only after cancelling ctx. Following Read will always return io.EOF.

Read must not be called from simultaneous goroutines.

Jump to

Keyboard shortcuts

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