From a6e2e0bba5605d9ca67f12cff7e309525518f831 Mon Sep 17 00:00:00 2001 From: Tejaswini Duggaraju Date: Fri, 6 Jul 2018 15:48:59 -0700 Subject: [PATCH] Select polling based watcher for Windows log watcher Signed-off-by: Tejaswini Duggaraju Upstream-commit: df84cdd091631f32abaedd805791db89ac5c83d4 Component: engine --- .../daemon/logger/loggerutils/logfile.go | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/components/engine/daemon/logger/loggerutils/logfile.go b/components/engine/daemon/logger/loggerutils/logfile.go index 6e3cda8648..96575e38c1 100644 --- a/components/engine/daemon/logger/loggerutils/logfile.go +++ b/components/engine/daemon/logger/loggerutils/logfile.go @@ -8,6 +8,7 @@ import ( "fmt" "io" "os" + "runtime" "strconv" "strings" "sync" @@ -641,9 +642,20 @@ func followLogs(f *os.File, logWatcher *logger.LogWatcher, notifyRotate chan int } func watchFile(name string) (filenotify.FileWatcher, error) { - fileWatcher, err := filenotify.New() - if err != nil { - return nil, err + var fileWatcher filenotify.FileWatcher + + if runtime.GOOS == "windows" { + // FileWatcher on Windows files is based on the syscall notifications which has an issue becuase of file caching. + // It is based on ReadDirectoryChangesW() which doesn't detect writes to the cache. It detects writes to disk only. + // Becuase of the OS lazy writing, we don't get notifications for file writes and thereby the watcher + // doesn't work. Hence for Windows we will use poll based notifier. + fileWatcher = filenotify.NewPollingWatcher() + } else { + var err error + fileWatcher, err = filenotify.New() + if err != nil { + return nil, err + } } logger := logrus.WithFields(logrus.Fields{ @@ -652,6 +664,7 @@ func watchFile(name string) (filenotify.FileWatcher, error) { }) if err := fileWatcher.Add(name); err != nil { + // we will retry using file poller. logger.WithError(err).Warnf("falling back to file poller") fileWatcher.Close() fileWatcher = filenotify.NewPollingWatcher() @@ -662,5 +675,6 @@ func watchFile(name string) (filenotify.FileWatcher, error) { return nil, err } } + return fileWatcher, nil }