diff --git a/daemon/logger/jsonfilelog/jsonfilelog_test.go b/daemon/logger/jsonfilelog/jsonfilelog_test.go index 162c685b24..ef840531a1 100644 --- a/daemon/logger/jsonfilelog/jsonfilelog_test.go +++ b/daemon/logger/jsonfilelog/jsonfilelog_test.go @@ -199,3 +199,50 @@ func TestJSONFileLoggerWithLabelsEnv(t *testing.T) { t.Fatalf("Wrong log attrs: %q, expected %q", extra, expected) } } + +func BenchmarkJSONFileLoggerWithReader(b *testing.B) { + b.StopTimer() + b.ResetTimer() + cid := "a7317399f3f857173c6179d44823594f8294678dea9999662e5c625b5a1c7657" + dir, err := ioutil.TempDir("", "json-logger-bench") + if err != nil { + b.Fatal(err) + } + defer os.RemoveAll(dir) + + l, err := New(logger.Context{ + ContainerID: cid, + LogPath: filepath.Join(dir, "container.log"), + }) + if err != nil { + b.Fatal(err) + } + defer l.Close() + msg := &logger.Message{ContainerID: cid, Line: []byte("line"), Source: "src1"} + jsonlog, err := (&jsonlog.JSONLog{Log: string(msg.Line) + "\n", Stream: msg.Source, Created: msg.Timestamp}).MarshalJSON() + if err != nil { + b.Fatal(err) + } + b.SetBytes(int64(len(jsonlog)+1) * 30) + + b.StartTimer() + + go func() { + for i := 0; i < b.N; i++ { + for j := 0; j < 30; j++ { + l.Log(msg) + } + } + l.Close() + }() + + lw := l.(logger.LogReader).ReadLogs(logger.ReadConfig{Follow: true}) + watchClose := lw.WatchClose() + for { + select { + case <-lw.Msg: + case <-watchClose: + return + } + } +} diff --git a/pkg/filenotify/poller.go b/pkg/filenotify/poller.go index 0d92afd4cb..5261085346 100644 --- a/pkg/filenotify/poller.go +++ b/pkg/filenotify/poller.go @@ -118,8 +118,6 @@ func (w *filePoller) Close() error { w.remove(name) delete(w.watches, name) } - close(w.events) - close(w.errors) return nil } @@ -146,6 +144,7 @@ func (w *filePoller) sendErr(e error, chClose <-chan struct{}) error { // watch is responsible for polling the specified file for changes // upon finding changes to a file or errors, sendEvent/sendErr is called func (w *filePoller) watch(f *os.File, lastFi os.FileInfo, chClose chan struct{}) { + defer f.Close() for { time.Sleep(watchWaitTime) select { diff --git a/pkg/filenotify/poller_test.go b/pkg/filenotify/poller_test.go index 0715c25868..4f5026237c 100644 --- a/pkg/filenotify/poller_test.go +++ b/pkg/filenotify/poller_test.go @@ -93,24 +93,6 @@ func TestPollerClose(t *testing.T) { t.Fatal(err) } - select { - case _, open := <-w.Events(): - if open { - t.Fatal("event chan should be closed") - } - default: - t.Fatal("event chan should be closed") - } - - select { - case _, open := <-w.Errors(): - if open { - t.Fatal("errors chan should be closed") - } - default: - t.Fatal("errors chan should be closed") - } - f, err := ioutil.TempFile("", "asdf") if err != nil { t.Fatal(err)