martin-helmich/prometheus-nginxlog-exporter

View on GitHub
pkg/tail/tailer.go

Summary

Maintainability
A
0 mins
Test Coverage
package tail

import (
    "io"
    "os"

    "github.com/martin-helmich/prometheus-nginxlog-exporter/log"
    "github.com/nxadm/tail"
)

type followerImpl struct {
    logger *log.Logger

    filename string
    t        *tail.Tail
    line     chan string
}

// NewFileFollower creates a new Follower instance for a given file (given by name)
func NewFileFollower(logger *log.Logger, filename string) (Follower, error) {
    f := &followerImpl{
        filename: filename,
        line:     make(chan string),
        logger:   logger,
    }

    if err := f.start(); err != nil {
        return nil, err
    }

    return f, nil
}

func (f *followerImpl) start() error {
    var seekInfo *tail.SeekInfo

    _, err := os.Stat(f.filename)
    if err != nil {
        if !os.IsNotExist(err) {
            return err
        }
    } else {
        seekInfo = &tail.SeekInfo{Offset: 0, Whence: io.SeekEnd}
    }

    t, err := tail.TailFile(f.filename, tail.Config{
        Follow:   true,
        ReOpen:   true,
        Poll:     true,
        Location: seekInfo,
        Logger:   f.logger,
    })

    if err != nil {
        return err
    }

    f.t = t
    return nil
}

func (f *followerImpl) OnError(cb func(error)) {
    go func() {
        err := f.t.Wait()
        if err != nil {
            cb(err)
        }
    }()
}

func (f *followerImpl) Lines() chan string {
    go func() {
        for n := range f.t.Lines {
            f.line <- n.Text
        }
    }()
    return f.line
}