log: fix prepFile fail on empty file or files without any newline

Actually, I think we can cancel to cut off invalid part from the end.
Just append new logs to the file would be more simple.
This commit is contained in:
hepengfei 2019-07-11 20:50:13 +08:00
parent 252150918c
commit 27a40c1629
2 changed files with 90 additions and 13 deletions

View file

@ -102,29 +102,20 @@ func prepFile(path string) (*countingWriter, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
_, err = f.Seek(-1, io.SeekEnd) fi, err := f.Stat()
if err != nil { if err != nil {
return nil, err return nil, err
} }
buf := make([]byte, 1) buf := make([]byte, 1)
var cut int64 var ns int64
for { for ns = fi.Size(); ns > 0; ns-- {
if _, err := f.Read(buf); err != nil { if _, err := f.ReadAt(buf, ns-1); err != nil {
return nil, err return nil, err
} }
if buf[0] == '\n' { if buf[0] == '\n' {
break break
} }
if _, err = f.Seek(-2, io.SeekCurrent); err != nil {
return nil, err
} }
cut++
}
fi, err := f.Stat()
if err != nil {
return nil, err
}
ns := fi.Size() - cut
if err = f.Truncate(ns); err != nil { if err = f.Truncate(ns); err != nil {
return nil, err return nil, err
} }

86
log/handler_test.go Normal file
View file

@ -0,0 +1,86 @@
package log
import (
"io/ioutil"
"os"
"testing"
)
func newTempFileWithData(data []byte) string {
for {
f, err := ioutil.TempFile("", "ethereum.log")
if err != nil {
continue
}
err = f.Truncate(0)
if err != nil {
continue
}
if len(data) != 0 {
_, err = f.Write(data)
if err != nil {
continue
}
}
name := f.Name()
_ = f.Close()
return name
}
}
func TestPrepFileWithEmptyFile(t *testing.T) {
tmpfile := newTempFileWithData(nil)
w, err := prepFile(tmpfile)
if err != nil {
t.Errorf("Expect nil, got %v", err)
}
w.Close()
defer os.Remove(tmpfile)
}
func TestPrepFileWithoutNewLine(t *testing.T) {
dataWithoutNewLine := make([]byte, 100)
for i := range dataWithoutNewLine {
dataWithoutNewLine[i] = 'A'
}
tmpfile := newTempFileWithData(dataWithoutNewLine)
w, err := prepFile(tmpfile)
if err != nil {
t.Errorf("Expect nil, got %v", err)
}
w.Close()
defer os.Remove(tmpfile)
}
func TestPrepFileWithNewLine(t *testing.T) {
dataWithoutNewLine := make([]byte, 100)
for i := range dataWithoutNewLine {
dataWithoutNewLine[i] = 'A'
}
dataWithoutNewLine[0] = '\n'
tmpfile := newTempFileWithData(dataWithoutNewLine)
w, err := prepFile(tmpfile)
if err != nil {
t.Errorf("Expect nil, got %v", err)
}
if w.count != 1 {
t.Errorf("Expect 1, got %v", w.count)
}
w.Close()
defer os.Remove(tmpfile)
}