Merge pull request #21309 from nalind/journal-error-reporting

Improve error reporting when following journals
This commit is contained in:
David Calavera 2016-03-30 16:15:34 -07:00
commit 0dac544448

View file

@ -63,11 +63,11 @@ package journald
// fds[0].events = POLLHUP; // fds[0].events = POLLHUP;
// fds[1].fd = sd_journal_get_fd(j); // fds[1].fd = sd_journal_get_fd(j);
// if (fds[1].fd < 0) { // if (fds[1].fd < 0) {
// return -1; // return fds[1].fd;
// } // }
// jevents = sd_journal_get_events(j); // jevents = sd_journal_get_events(j);
// if (jevents < 0) { // if (jevents < 0) {
// return -1; // return jevents;
// } // }
// fds[1].events = jevents; // fds[1].events = jevents;
// sd_journal_get_timeout(j, &when); // sd_journal_get_timeout(j, &when);
@ -81,7 +81,7 @@ package journald
// i = poll(fds, 2, timeout); // i = poll(fds, 2, timeout);
// if ((i == -1) && (errno != EINTR)) { // if ((i == -1) && (errno != EINTR)) {
// /* An unexpected error. */ // /* An unexpected error. */
// return -1; // return (errno != 0) ? -errno : -EINTR;
// } // }
// if (fds[0].revents & POLLHUP) { // if (fds[0].revents & POLLHUP) {
// /* The close notification pipe was closed. */ // /* The close notification pipe was closed. */
@ -101,6 +101,7 @@ import (
"time" "time"
"unsafe" "unsafe"
"github.com/Sirupsen/logrus"
"github.com/coreos/go-systemd/journal" "github.com/coreos/go-systemd/journal"
"github.com/docker/docker/daemon/logger" "github.com/docker/docker/daemon/logger"
) )
@ -177,9 +178,18 @@ func (s *journald) followJournal(logWatcher *logger.LogWatcher, config logger.Re
s.readers.readers[logWatcher] = logWatcher s.readers.readers[logWatcher] = logWatcher
s.readers.mu.Unlock() s.readers.mu.Unlock()
go func() { go func() {
// Keep copying journal data out until we're notified to stop. // Keep copying journal data out until we're notified to stop
for C.wait_for_data_or_close(j, pfd[0]) == 1 { // or we hit an error.
status := C.wait_for_data_or_close(j, pfd[0])
for status == 1 {
cursor = s.drainJournal(logWatcher, config, j, cursor) cursor = s.drainJournal(logWatcher, config, j, cursor)
status = C.wait_for_data_or_close(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"])
} }
// Clean up. // Clean up.
C.close(pfd[0]) C.close(pfd[0])
@ -293,14 +303,21 @@ func (s *journald) readLogs(logWatcher *logger.LogWatcher, config logger.ReadCon
} }
cursor = s.drainJournal(logWatcher, config, j, "") cursor = s.drainJournal(logWatcher, config, j, "")
if config.Follow { if config.Follow {
// Create a pipe that we can poll at the same time as the journald descriptor. // Allocate a descriptor for following the journal, if we'll
if C.pipe(&pipes[0]) == C.int(-1) { // need one. Do it here so that we can report if it fails.
logWatcher.Err <- fmt.Errorf("error opening journald close notification pipe") if fd := C.sd_journal_get_fd(j); fd < C.int(0) {
logWatcher.Err <- fmt.Errorf("error opening journald follow descriptor: %q", C.GoString(C.strerror(-fd)))
} else { } else {
s.followJournal(logWatcher, config, j, pipes, cursor) // Create a pipe that we can poll at the same time as
// Let followJournal handle freeing the journal context // the journald descriptor.
// object and closing the channel. if C.pipe(&pipes[0]) == C.int(-1) {
following = true logWatcher.Err <- fmt.Errorf("error opening journald close notification pipe")
} else {
s.followJournal(logWatcher, config, j, pipes, cursor)
// Let followJournal handle freeing the journal context
// object and closing the channel.
following = true
}
} }
} }
return return