diff --git a/daemon/logger/loggerutils/follow.go b/daemon/logger/loggerutils/follow.go index d2e63c133a..cef184cc08 100644 --- a/daemon/logger/loggerutils/follow.go +++ b/daemon/logger/loggerutils/follow.go @@ -21,6 +21,7 @@ type follow struct { fileWatcher filenotify.FileWatcher logWatcher *logger.LogWatcher producerGone <-chan struct{} + draining bool notifyRotate, notifyEvict chan interface{} oldSize int64 retries int @@ -99,7 +100,14 @@ func (fl *follow) waitRead() error { } return err case <-fl.producerGone: - return errDone + // There may be messages written out which the fileWatcher has + // not yet notified us about. + if fl.draining { + return errDone + } + fl.draining = true + fl.dec.Reset(fl.file) + return nil case <-fl.logWatcher.WatchConsumerGone(): return errDone } diff --git a/daemon/logger/loggerutils/logfile.go b/daemon/logger/loggerutils/logfile.go index 3f65c52685..b28d5df677 100644 --- a/daemon/logger/loggerutils/logfile.go +++ b/daemon/logger/loggerutils/logfile.go @@ -440,11 +440,10 @@ func (w *LogFile) readLogsLocked(config logger.ReadConfig, watcher *logger.LogWa w.mu.RLock() } - if !config.Follow || w.closed { - w.mu.RUnlock() + w.mu.RUnlock() + if !config.Follow { return } - w.mu.RUnlock() notifyRotate := w.notifyReaders.SubscribeTopic(func(i interface{}) bool { _, ok := i.(struct{}) diff --git a/daemon/logger/loggerutils/logfile_test.go b/daemon/logger/loggerutils/logfile_test.go index ecd0c87bf3..3c62f52abc 100644 --- a/daemon/logger/loggerutils/logfile_test.go +++ b/daemon/logger/loggerutils/logfile_test.go @@ -179,7 +179,6 @@ func TestFollowLogsProducerGone(t *testing.T) { t.Logf("logDecode() closed after sending %d messages\n", sent) return io.EOF default: - t.Fatal("logDecode() called after closing!") return io.EOF } }}