If specified the MaxLineSize, then set to the bufio.reader MaxLineSize.

This commit is contained in:
YAMASAKI masahide 2014-02-19 08:46:36 +09:00 committed by YAMASAKI Masahide
parent 7ccd8397a1
commit 6a3ddb6ced
2 changed files with 42 additions and 4 deletions

16
tail.go
View File

@ -171,7 +171,7 @@ func (tail *Tail) reopen() error {
func (tail *Tail) readLine() ([]byte, error) { func (tail *Tail) readLine() ([]byte, error) {
line, isPrefix, err := tail.reader.ReadLine() line, isPrefix, err := tail.reader.ReadLine()
if !isPrefix { if !isPrefix || tail.MaxLineSize > 0 {
return line, err return line, err
} }
@ -208,7 +208,7 @@ func (tail *Tail) tailFileSync() {
} }
} }
tail.reader = bufio.NewReader(tail.file) tail.reader = tail.newReader()
// Read line by line. // Read line by line.
for { for {
@ -289,7 +289,7 @@ func (tail *Tail) waitForChanges() error {
return err return err
} }
tail.Logger.Printf("Successfully reopened %s", tail.Filename) tail.Logger.Printf("Successfully reopened %s", tail.Filename)
tail.reader = bufio.NewReader(tail.file) tail.reader = tail.newReader()
return nil return nil
} else { } else {
tail.Logger.Printf("Stopping tail as file no longer exists: %s", tail.Filename) tail.Logger.Printf("Stopping tail as file no longer exists: %s", tail.Filename)
@ -302,7 +302,7 @@ func (tail *Tail) waitForChanges() error {
return err return err
} }
tail.Logger.Printf("Successfully reopened truncated %s", tail.Filename) tail.Logger.Printf("Successfully reopened truncated %s", tail.Filename)
tail.reader = bufio.NewReader(tail.file) tail.reader = tail.newReader()
return nil return nil
case <-tail.Dying(): case <-tail.Dying():
return ErrStop return ErrStop
@ -310,6 +310,14 @@ func (tail *Tail) waitForChanges() error {
panic("unreachable") panic("unreachable")
} }
func (tail *Tail) newReader() *bufio.Reader {
if tail.MaxLineSize > 0 {
return bufio.NewReaderSize(tail.file, tail.MaxLineSize+2)
} else {
return bufio.NewReader(tail.file)
}
}
// sendLine sends the line(s) to Lines channel, splitting longer lines // sendLine sends the line(s) to Lines channel, splitting longer lines
// if necessary. Return false if rate limit is reached. // if necessary. Return false if rate limit is reached.
func (tail *Tail) sendLine(line []byte) bool { func (tail *Tail) sendLine(line []byte) bool {

View File

@ -10,6 +10,7 @@ import (
_ "fmt" _ "fmt"
"io/ioutil" "io/ioutil"
"os" "os"
"strings"
"testing" "testing"
"time" "time"
) )
@ -66,6 +67,35 @@ func TestMaxLineSize(_t *testing.T) {
Cleanup() Cleanup()
} }
func TestOver4096ByteLine(_t *testing.T) {
t := NewTailTest("Over4096ByteLine", _t)
testString := strings.Repeat("a", 4097)
t.CreateFile("test.txt", "test\n"+testString+"\nhello\nworld\n")
tail := t.StartTail("test.txt", Config{Follow: true, Location: nil})
go t.VerifyTailOutput(tail, []string{"test", testString, "hello", "world"})
// Delete after a reasonable delay, to give tail sufficient time
// to read all lines.
<-time.After(100 * time.Millisecond)
t.RemoveFile("test.txt")
tail.Stop()
Cleanup()
}
func TestOver4096ByteLineWithSetMaxLineSize(_t *testing.T) {
t := NewTailTest("Over4096ByteLineMaxLineSize", _t)
testString := strings.Repeat("a", 4097)
t.CreateFile("test.txt", "test\r\n"+testString+"\r\nhello\r\nworld\r\n")
tail := t.StartTail("test.txt", Config{Follow: true, Location: nil, MaxLineSize: 4097})
go t.VerifyTailOutput(tail, []string{"test", testString, "hello", "world"})
// Delete after a reasonable delay, to give tail sufficient time
// to read all lines.
<-time.After(100 * time.Millisecond)
t.RemoveFile("test.txt")
tail.Stop()
Cleanup()
}
func TestLocationFull(_t *testing.T) { func TestLocationFull(_t *testing.T) {
t := NewTailTest("location-full", _t) t := NewTailTest("location-full", _t)
t.CreateFile("test.txt", "hello\nworld\n") t.CreateFile("test.txt", "hello\nworld\n")