Merge pull request #34 from thaJeztah/18.06-backport-logissue

[18.06] backport select polling based watcher for Windows log watcher
diff --git a/daemon/logger/loggerutils/logfile.go b/daemon/logger/loggerutils/logfile.go
index 6e3cda8..96575e3 100644
--- a/daemon/logger/loggerutils/logfile.go
+++ b/daemon/logger/loggerutils/logfile.go
@@ -8,6 +8,7 @@
 	"fmt"
 	"io"
 	"os"
+	"runtime"
 	"strconv"
 	"strings"
 	"sync"
@@ -641,9 +642,20 @@
 }
 
 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 @@
 	})
 
 	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 @@
 			return nil, err
 		}
 	}
+
 	return fileWatcher, nil
 }