diff --git a/log/slow/parser.go b/log/slow/parser.go index 9eb72a3..9f30759 100644 --- a/log/slow/parser.go +++ b/log/slow/parser.go @@ -61,7 +61,7 @@ var ( // SlowLogParser parses a MySQL slow log. It implements the LogParser interface. type SlowLogParser struct { - reader io.ReadSeeker + reader io.Reader opt log.Options // -- stopChan chan bool @@ -78,7 +78,7 @@ type SlowLogParser struct { } // NewSlowLogParser returns a new SlowLogParser that reads from the open file. -func NewSlowLogParser(r io.ReadSeeker, opt log.Options) *SlowLogParser { +func NewSlowLogParser(r io.Reader, opt log.Options) *SlowLogParser { if opt.DefaultLocation == nil { // Old MySQL format assumes time is taken from SYSTEM. opt.DefaultLocation = time.Local @@ -130,8 +130,14 @@ func (p *SlowLogParser) Start() error { // Seek to the offset, if any. // @todo error if start off > file size if p.opt.StartOffset > 0 { - if _, err := p.reader.Seek(int64(p.opt.StartOffset), os.SEEK_SET); err != nil { - return err + if reader, ok := p.reader.(io.ReadSeeker); ok { + if _, err := reader.Seek(int64(p.opt.StartOffset), os.SEEK_SET); err != nil { + return err + } + } else { + if _, err := io.CopyN(io.Discard, p.reader, int64(p.opt.StartOffset)); err != nil { + return err + } } } diff --git a/log/slow/parser_test.go b/log/slow/parser_test.go index 1cb73bb..ff99f4f 100644 --- a/log/slow/parser_test.go +++ b/log/slow/parser_test.go @@ -32,6 +32,7 @@ package slow_test import ( "bytes" + "io" l "log" "os" "path" @@ -1986,3 +1987,27 @@ SELECT fruit FROM trees; assert.NotEqual(t, 0, len(got)) } + +func TestParseFromMultiReader(t *testing.T) { + query1 := ` +# Time: 071218 11:48:27 +# User@Host: [SQL_SLAVE] @ [] +# Thread_id: 3 Schema: db1 +# Query_time: 0.000012 Lock_time: 0.000000 Rows_sent: 0 Rows_examined: 0` + query2 := ` +use db2; +SELECT fruit FROM trees; +` + + buf1 := bytes.NewReader([]byte(query1)) + buf2 := bytes.NewReader([]byte(query2)) + p := parser.NewSlowLogParser(io.MultiReader(buf1, buf2), opt) + + got := []log.Event{} + go p.Start() + for e := range p.EventChan() { + got = append(got, *e) + } + + assert.NotEqual(t, 0, len(got)) +}