From 7c251eb224e0e2abbde6ac4248c1a3147321cc06 Mon Sep 17 00:00:00 2001 From: Andy Goldstein Date: Wed, 21 Dec 2016 09:17:12 -0500 Subject: [PATCH] journald logs: drain 1 more time at container exit In the journald log driver, attempt to drain the journal 1 more time after being told to stop following the log. Due to a possible race condition, sometimes data is written to the journal at almost the same time the log watch is closed, and depending on the order of operations, sometimes you miss the last journal entry. Signed-off-by: Andy Goldstein Upstream-commit: 76f58d7294259bd9bbc91082077d32bbbcb9fd9a Component: engine --- .../engine/daemon/logger/journald/read.go | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/components/engine/daemon/logger/journald/read.go b/components/engine/daemon/logger/journald/read.go index d91eb809bc..541fab7055 100644 --- a/components/engine/daemon/logger/journald/read.go +++ b/components/engine/daemon/logger/journald/read.go @@ -245,20 +245,28 @@ func (s *journald) followJournal(logWatcher *logger.LogWatcher, config logger.Re s.readers.mu.Lock() s.readers.readers[logWatcher] = logWatcher s.readers.mu.Unlock() + go func() { - // Keep copying journal data out until we're notified to stop - // or we hit an error. - status := C.wait_for_data_cancelable(j, pfd[0]) - for status == 1 { + for { + // Keep copying journal data out until we're notified to stop + // or we hit an error. + status := C.wait_for_data_cancelable(j, pfd[0]) + if status < 0 { + cerrstr := C.strerror(C.int(-status)) + errstr := C.GoString(cerrstr) + fmtstr := "error %q while attempting to follow journal for container %q" + logrus.Errorf(fmtstr, errstr, s.vars["CONTAINER_ID_FULL"]) + break + } + cursor = s.drainJournal(logWatcher, config, j, cursor) - status = C.wait_for_data_cancelable(j, pfd[0]) - } - if status < 0 { - cerrstr := C.strerror(C.int(-status)) - errstr := C.GoString(cerrstr) - fmtstr := "error %q while attempting to follow journal for container %q" - logrus.Errorf(fmtstr, errstr, s.vars["CONTAINER_ID_FULL"]) + + if status != 1 { + // We were notified to stop + break + } } + // Clean up. C.close(pfd[0]) s.readers.mu.Lock() @@ -267,6 +275,7 @@ func (s *journald) followJournal(logWatcher *logger.LogWatcher, config logger.Re C.sd_journal_close(j) close(logWatcher.Msg) }() + // Wait until we're told to stop. select { case <-logWatcher.WatchClose():