From 23023fa5ed01b5e1e2580b854b331eeff0992f0b Mon Sep 17 00:00:00 2001 From: Brian Goff Date: Fri, 31 Jul 2015 16:49:07 -0400 Subject: [PATCH] Ensure reader position is at the end after tailing After tailing a file, if the number of lines requested is > the number of lines in the file, this would cause a json unmarshalling error to occur when we later try to go follow the file. So brute force set it to the end if any tailing occurred. There is potential that there could be some missing log messages if logs are being written very quickly, however I was not able to make this happen even with `while true; do echo hello; done`, so this is probably acceptable. While testing this I also found a panic in LogWatcher.Close can be called twice due to a race. Fix channel close to only close when there has been no signal to the channel. Signed-off-by: Brian Goff Upstream-commit: c57faa91e2dab72a0a0905dc10e5cbdf55b545f5 Component: engine --- .../engine/daemon/logger/jsonfilelog/jsonfilelog.go | 3 ++- components/engine/daemon/logger/logger.go | 9 ++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/components/engine/daemon/logger/jsonfilelog/jsonfilelog.go b/components/engine/daemon/logger/jsonfilelog/jsonfilelog.go index e3fb98dc6b..d19f8ff299 100644 --- a/components/engine/daemon/logger/jsonfilelog/jsonfilelog.go +++ b/components/engine/daemon/logger/jsonfilelog/jsonfilelog.go @@ -267,7 +267,8 @@ func (l *JSONFileLogger) readLogs(logWatcher *logger.LogWatcher, config logger.R if !config.Follow { return } - if config.Tail == 0 { + + if config.Tail >= 0 { latestFile.Seek(0, os.SEEK_END) } diff --git a/components/engine/daemon/logger/logger.go b/components/engine/daemon/logger/logger.go index ed245fcc1d..8a2acccf6e 100644 --- a/components/engine/daemon/logger/logger.go +++ b/components/engine/daemon/logger/logger.go @@ -9,6 +9,7 @@ package logger import ( "errors" + "sync" "time" "github.com/docker/docker/pkg/timeutils" @@ -58,6 +59,7 @@ type LogWatcher struct { // For sending error messages that occur while while reading logs. Err chan error closeNotifier chan struct{} + closeOnce sync.Once } // NewLogWatcher returns a new LogWatcher. @@ -71,7 +73,12 @@ func NewLogWatcher() *LogWatcher { // Close notifies the underlying log reader to stop. func (w *LogWatcher) Close() { - close(w.closeNotifier) + // only close if not already closed + select { + case <-w.closeNotifier: + default: + close(w.closeNotifier) + } } // WatchClose returns a channel receiver that receives notification