Browse Source

Merge pull request #37412 from AzureCR/naduggar/logissue

Select polling based watcher for docker log file watcher on Windows
Sebastiaan van Stijn 7 years ago
parent
commit
678d4b3a6d
1 changed files with 17 additions and 3 deletions
  1. 17 3
      daemon/logger/loggerutils/logfile.go

+ 17 - 3
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
 }